mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-22 00:00:55 +01:00
Compare commits
51 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8220180133 | ||
|
|
a206a23980 | ||
|
|
865c3a2383 | ||
|
|
f03304a9c7 | ||
|
|
bdde31d787 | ||
|
|
bfd471f53e | ||
|
|
84d7c981dc | ||
|
|
24324d83e8 | ||
|
|
b7ccd48dd8 | ||
|
|
776d0f3459 | ||
|
|
e4ff4e6898 | ||
|
|
298a771494 | ||
|
|
51d9b435cd | ||
|
|
f35e21e2e4 | ||
|
|
683bcb9154 | ||
|
|
c4679ad0f1 | ||
|
|
2f7a9997c8 | ||
|
|
026c5f7617 | ||
|
|
222e3de4be | ||
|
|
910bd45756 | ||
|
|
838e8c9166 | ||
|
|
e2a186af10 | ||
|
|
461764cbbe | ||
|
|
3b8848fa4e | ||
|
|
3cac997e19 | ||
|
|
c891967b6f | ||
|
|
c285051c08 | ||
|
|
2ce73dbe85 | ||
|
|
d9c6b09ac4 | ||
|
|
2ea5fa0710 | ||
|
|
5cbf75324d | ||
|
|
2fad3d34b7 | ||
|
|
77cd030ac3 | ||
|
|
ed54768f5f | ||
|
|
83082f04a4 | ||
|
|
103849419a | ||
|
|
0a27bd065e | ||
|
|
b22c884231 | ||
|
|
dc8adc3b48 | ||
|
|
178152f604 | ||
|
|
a790fa46f4 | ||
|
|
9b8eb4d690 | ||
|
|
172f006020 | ||
|
|
efae3da41d | ||
|
|
3df62878c3 | ||
|
|
fdbf76d4f4 | ||
|
|
c39b06866e | ||
|
|
4968232490 | ||
|
|
7629d36a53 | ||
|
|
3f64753779 | ||
|
|
f1e1fb4bde |
2
base58.h
2
base58.h
@@ -152,7 +152,7 @@ inline bool DecodeBase58Check(const string& str, vector<unsigned char>& vchRet)
|
||||
|
||||
|
||||
|
||||
static const unsigned char ADDRESSVERSION = 0;
|
||||
#define ADDRESSVERSION ((unsigned char)(fTestNet ? 111 : 0))
|
||||
|
||||
inline string Hash160ToAddress(uint160 hash160)
|
||||
{
|
||||
|
||||
@@ -12,12 +12,8 @@ WINDOWS BUILD NOTES
|
||||
Compilers Supported
|
||||
-------------------
|
||||
MinGW GCC (recommended)
|
||||
|
||||
MSVC 6.0 SP6: You'll need Boost version 1.34 because they dropped support
|
||||
for MSVC 6.0 after that. However, they didn't add Asio until 1.35.
|
||||
You should still be able to build with MSVC 6.0 by adding Asio to 1.34 by
|
||||
unpacking boost_asio_*.zip into the boost directory:
|
||||
http://sourceforge.net/projects/asio/files/asio
|
||||
http://tdm-gcc.tdragon.net/ has an easy installer. Go back a few versions
|
||||
for a little older gcc like gcc 4.4.?.
|
||||
|
||||
MSVC 8.0 (2005) SP1 has been tested. Note: MSVC 7.0 and up have a habit of
|
||||
linking to runtime DLLs that are not installed on XP by default.
|
||||
@@ -67,8 +63,7 @@ nmake -f makefile.vc
|
||||
|
||||
OpenSSL
|
||||
-------
|
||||
Bitcoin does not use any encryption. If you want to do a no-everything
|
||||
build of OpenSSL to exclude encryption routines, a few patches are required.
|
||||
If you want to exclude unused optional algorithms, a few patches are required.
|
||||
(instructions for OpenSSL v0.9.8k)
|
||||
|
||||
Edit engines\e_gmp.c and engines\e_capi.c and add this #ifndef around
|
||||
@@ -92,7 +87,7 @@ Build
|
||||
cd \openssl
|
||||
ms\mingw32.bat
|
||||
|
||||
If you want to use it with MSVC, generate the .lib file
|
||||
If you're using MSVC, generate the .lib file
|
||||
lib /machine:i386 /def:ms\libeay32.def /out:out\libeay32.lib
|
||||
|
||||
|
||||
|
||||
@@ -21,7 +21,8 @@ or Boost 1.37: sudo apt-get install libboost1.37-dev
|
||||
|
||||
If using Boost 1.37, append -mt to the boost libraries in the makefile.
|
||||
|
||||
We're now using wxWidgets 2.9, which uses UTF-8. Don't try 2.8, it won't work.
|
||||
We're using wxWidgets 2.9.0, which uses UTF-8. Don't try 2.8, it won't work.
|
||||
The build hasn't been updated to work with wxWidgets 2.9.1 yet.
|
||||
|
||||
You need to download wxWidgets from http://www.wxwidgets.org/downloads/
|
||||
and build it yourself. See the build instructions and configure parameters
|
||||
|
||||
41
coding.txt
Normal file
41
coding.txt
Normal file
@@ -0,0 +1,41 @@
|
||||
Please be consistent with the existing coding style.
|
||||
|
||||
Block style:
|
||||
|
||||
bool Function(char* psz, int n)
|
||||
{
|
||||
// Comment summarising what this section of code does
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
// When something fails, return early
|
||||
if (!Something())
|
||||
return false;
|
||||
...
|
||||
}
|
||||
|
||||
// Success return is usually at the end
|
||||
return true;
|
||||
}
|
||||
|
||||
- ANSI/Allman block style
|
||||
- 4 space indenting, no tabs
|
||||
- No extra spaces inside parenthesis; please don't do ( this )
|
||||
- No space after function names, one space after if, for and while
|
||||
|
||||
Variable names begin with the type in lowercase, like nSomeVariable.
|
||||
Please don't put the first word of the variable name in lowercase like
|
||||
someVariable.
|
||||
|
||||
Common types:
|
||||
n integer number: short, unsigned short, int, unsigned int,
|
||||
int64, uint64, sometimes char if used as a number
|
||||
d double, float
|
||||
f flag
|
||||
hash uint256
|
||||
p pointer or array, one p for each level of indirection
|
||||
psz pointer to null terminated string
|
||||
str string object
|
||||
v vector or similar list objects
|
||||
map map or multimap
|
||||
set set or multiset
|
||||
bn CBigNum
|
||||
@@ -184,7 +184,8 @@ public:
|
||||
|
||||
void deallocate(void *p, size_type n)
|
||||
{
|
||||
assert(false);
|
||||
//// Bitcoin: don't know why this trips, probably a false alarm, depends on the compiler used.
|
||||
//assert(false);
|
||||
}
|
||||
|
||||
size_type max_size() const {return 0;}
|
||||
|
||||
219
db.cpp
219
db.cpp
@@ -8,7 +8,7 @@ void ThreadFlushWalletDB(void* parg);
|
||||
|
||||
|
||||
unsigned int nWalletDBUpdated;
|
||||
|
||||
uint64 nAccountingEntryNumber = 0;
|
||||
|
||||
|
||||
|
||||
@@ -77,7 +77,6 @@ CDB::CDB(const char* pszFile, const char* pszMode) : pdb(NULL)
|
||||
DB_INIT_MPOOL |
|
||||
DB_INIT_TXN |
|
||||
DB_THREAD |
|
||||
DB_PRIVATE |
|
||||
DB_RECOVER,
|
||||
S_IRUSR | S_IWUSR);
|
||||
if (ret > 0)
|
||||
@@ -133,6 +132,8 @@ void CDB::Close()
|
||||
|
||||
// Flush database activity from memory pool to disk log
|
||||
unsigned int nMinutes = 0;
|
||||
if (fReadOnly)
|
||||
nMinutes = 1;
|
||||
if (strFile == "addr.dat")
|
||||
nMinutes = 2;
|
||||
if (strFile == "blkindex.dat" && IsInitialBlockDownload() && nBestHeight % 500 != 0)
|
||||
@@ -466,7 +467,7 @@ bool CTxDB::LoadBlockIndex()
|
||||
CBlockIndex* pindexFork = NULL;
|
||||
for (CBlockIndex* pindex = pindexBest; pindex && pindex->pprev; pindex = pindex->pprev)
|
||||
{
|
||||
if (pindex->nHeight < 74000 && !mapArgs.count("-checkblocks"))
|
||||
if (pindex->nHeight < nBestHeight-2500 && !mapArgs.count("-checkblocks"))
|
||||
break;
|
||||
CBlock block;
|
||||
if (!block.ReadFromDisk(pindex))
|
||||
@@ -504,6 +505,11 @@ bool CAddrDB::WriteAddress(const CAddress& addr)
|
||||
return Write(make_pair(string("addr"), addr.GetKey()), addr);
|
||||
}
|
||||
|
||||
bool CAddrDB::EraseAddress(const CAddress& addr)
|
||||
{
|
||||
return Erase(make_pair(string("addr"), addr.GetKey()));
|
||||
}
|
||||
|
||||
bool CAddrDB::LoadAddresses()
|
||||
{
|
||||
CRITICAL_BLOCK(cs_mapAddresses)
|
||||
@@ -555,11 +561,6 @@ bool CAddrDB::LoadAddresses()
|
||||
pcursor->close();
|
||||
|
||||
printf("Loaded %d addresses\n", mapAddresses.size());
|
||||
|
||||
// Fix for possible bug that manifests in mapAddresses.count in irc.cpp,
|
||||
// just need to call count here and it doesn't happen there. The bug was the
|
||||
// pack pragma in irc.cpp and has been fixed, but I'm not in a hurry to delete this.
|
||||
mapAddresses.count(vector<unsigned char>(18));
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -577,10 +578,85 @@ bool LoadAddresses()
|
||||
// CWalletDB
|
||||
//
|
||||
|
||||
static set<int64> setKeyPool;
|
||||
static CCriticalSection cs_setKeyPool;
|
||||
|
||||
bool CWalletDB::ReadAccount(const string& strAccount, CAccount& account)
|
||||
{
|
||||
account.SetNull();
|
||||
return Read(make_pair(string("acc"), strAccount), account);
|
||||
}
|
||||
|
||||
bool CWalletDB::WriteAccount(const string& strAccount, const CAccount& account)
|
||||
{
|
||||
return Write(make_pair(string("acc"), strAccount), account);
|
||||
}
|
||||
|
||||
bool CWalletDB::WriteAccountingEntry(const string& strAccount, const CAccountingEntry& acentry)
|
||||
{
|
||||
return Write(make_tuple(string("acentry"), strAccount, ++nAccountingEntryNumber), acentry);
|
||||
}
|
||||
|
||||
int64 CWalletDB::GetAccountCreditDebit(const string& strAccount)
|
||||
{
|
||||
list<CAccountingEntry> entries;
|
||||
ListAccountCreditDebit(strAccount, entries);
|
||||
|
||||
int64 nCreditDebit = 0;
|
||||
foreach (const CAccountingEntry& entry, entries)
|
||||
nCreditDebit += entry.nCreditDebit;
|
||||
|
||||
return nCreditDebit;
|
||||
}
|
||||
|
||||
void CWalletDB::ListAccountCreditDebit(const string& strAccount, list<CAccountingEntry>& entries)
|
||||
{
|
||||
int64 nCreditDebit = 0;
|
||||
|
||||
Dbc* pcursor = GetCursor();
|
||||
if (!pcursor)
|
||||
throw runtime_error("CWalletDB::ListAccountCreditDebit() : cannot create DB cursor");
|
||||
unsigned int fFlags = DB_SET_RANGE;
|
||||
loop
|
||||
{
|
||||
// Read next record
|
||||
CDataStream ssKey;
|
||||
if (fFlags == DB_SET_RANGE)
|
||||
ssKey << make_tuple(string("acentry"), strAccount, uint64(0));
|
||||
CDataStream ssValue;
|
||||
int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags);
|
||||
fFlags = DB_NEXT;
|
||||
if (ret == DB_NOTFOUND)
|
||||
break;
|
||||
else if (ret != 0)
|
||||
{
|
||||
pcursor->close();
|
||||
throw runtime_error("CWalletDB::ListAccountCreditDebit() : error scanning DB");
|
||||
}
|
||||
|
||||
// Unserialize
|
||||
string strType;
|
||||
ssKey >> strType;
|
||||
if (strType != "acentry")
|
||||
break;
|
||||
string strAccountName;
|
||||
ssKey >> strAccountName;
|
||||
if (strAccountName != strAccount)
|
||||
break;
|
||||
|
||||
CAccountingEntry acentry;
|
||||
ssValue >> acentry;
|
||||
entries.push_back(acentry);
|
||||
}
|
||||
|
||||
pcursor->close();
|
||||
}
|
||||
|
||||
bool CWalletDB::LoadWallet()
|
||||
{
|
||||
vchDefaultKey.clear();
|
||||
int nFileVersion = 0;
|
||||
vector<uint256> vWalletUpgrade;
|
||||
|
||||
// Modify defaults
|
||||
#ifndef __WXMSW__
|
||||
@@ -630,6 +706,25 @@ bool CWalletDB::LoadWallet()
|
||||
if (wtx.GetHash() != hash)
|
||||
printf("Error in wallet.dat, hash mismatch\n");
|
||||
|
||||
// Undo serialize changes in 31600
|
||||
if (31404 <= wtx.fTimeReceivedIsTxTime && wtx.fTimeReceivedIsTxTime <= 31703)
|
||||
{
|
||||
if (!ssValue.empty())
|
||||
{
|
||||
char fTmp;
|
||||
char fUnused;
|
||||
ssValue >> fTmp >> fUnused >> wtx.strFromAccount;
|
||||
printf("LoadWallet() upgrading tx ver=%d %d '%s' %s\n", wtx.fTimeReceivedIsTxTime, fTmp, wtx.strFromAccount.c_str(), hash.ToString().c_str());
|
||||
wtx.fTimeReceivedIsTxTime = fTmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("LoadWallet() repairing tx ver=%d %s\n", wtx.fTimeReceivedIsTxTime, hash.ToString().c_str());
|
||||
wtx.fTimeReceivedIsTxTime = 0;
|
||||
}
|
||||
vWalletUpgrade.push_back(hash);
|
||||
}
|
||||
|
||||
//// debug print
|
||||
//printf("LoadWallet %s\n", wtx.GetHash().ToString().c_str());
|
||||
//printf(" %12I64d %s %s %s\n",
|
||||
@@ -638,6 +733,15 @@ bool CWalletDB::LoadWallet()
|
||||
// wtx.hashBlock.ToString().substr(0,20).c_str(),
|
||||
// wtx.mapValue["message"].c_str());
|
||||
}
|
||||
else if (strType == "acentry")
|
||||
{
|
||||
string strAccount;
|
||||
ssKey >> strAccount;
|
||||
uint64 nNumber;
|
||||
ssKey >> nNumber;
|
||||
if (nNumber > nAccountingEntryNumber)
|
||||
nAccountingEntryNumber = nNumber;
|
||||
}
|
||||
else if (strType == "key" || strType == "wkey")
|
||||
{
|
||||
vector<unsigned char> vchPubKey;
|
||||
@@ -655,6 +759,12 @@ bool CWalletDB::LoadWallet()
|
||||
{
|
||||
ssValue >> vchDefaultKey;
|
||||
}
|
||||
else if (strType == "pool")
|
||||
{
|
||||
int64 nIndex;
|
||||
ssKey >> nIndex;
|
||||
setKeyPool.insert(nIndex);
|
||||
}
|
||||
else if (strType == "version")
|
||||
{
|
||||
ssValue >> nFileVersion;
|
||||
@@ -684,6 +794,9 @@ bool CWalletDB::LoadWallet()
|
||||
pcursor->close();
|
||||
}
|
||||
|
||||
foreach(uint256 hash, vWalletUpgrade)
|
||||
WriteTx(hash, mapWallet[hash]);
|
||||
|
||||
printf("nFileVersion = %d\n", nFileVersion);
|
||||
printf("fGenerateBitcoins = %d\n", fGenerateBitcoins);
|
||||
printf("nTransactionFee = %"PRI64d"\n", nTransactionFee);
|
||||
@@ -694,14 +807,6 @@ bool CWalletDB::LoadWallet()
|
||||
printf("addrProxy = %s\n", addrProxy.ToString().c_str());
|
||||
|
||||
|
||||
// The transaction fee setting won't be needed for many years to come.
|
||||
// Setting it to zero here in case they set it to something in an earlier version.
|
||||
if (nTransactionFee != 0)
|
||||
{
|
||||
nTransactionFee = 0;
|
||||
WriteSetting("nTransactionFee", nTransactionFee);
|
||||
}
|
||||
|
||||
// Upgrade
|
||||
if (nFileVersion < VERSION)
|
||||
{
|
||||
@@ -712,6 +817,7 @@ bool CWalletDB::LoadWallet()
|
||||
WriteVersion(VERSION);
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -820,10 +926,15 @@ void BackupWallet(const string& strDest)
|
||||
mapFileUseCount.erase(strFile);
|
||||
|
||||
// Copy wallet.dat
|
||||
filesystem::path pathSrc(GetDataDir() + "/" + strFile);
|
||||
filesystem::path pathDest(strDest);
|
||||
if (filesystem::is_directory(pathDest))
|
||||
pathDest = pathDest / strFile;
|
||||
filesystem::copy_file(filesystem::path(GetDataDir() + "/" + strFile), pathDest, filesystem::copy_option::overwrite_if_exists);
|
||||
#if BOOST_VERSION >= 104000
|
||||
filesystem::copy_file(pathSrc, pathDest, filesystem::copy_option::overwrite_if_exists);
|
||||
#else
|
||||
filesystem::copy_file(pathSrc, pathDest);
|
||||
#endif
|
||||
printf("copied wallet.dat to %s\n", pathDest.string().c_str());
|
||||
|
||||
return;
|
||||
@@ -832,3 +943,77 @@ void BackupWallet(const string& strDest)
|
||||
Sleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CWalletDB::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool)
|
||||
{
|
||||
nIndex = -1;
|
||||
keypool.vchPubKey.clear();
|
||||
CRITICAL_BLOCK(cs_main)
|
||||
CRITICAL_BLOCK(cs_mapWallet)
|
||||
CRITICAL_BLOCK(cs_setKeyPool)
|
||||
{
|
||||
// Top up key pool
|
||||
int64 nTargetSize = max(GetArg("-keypool", 100), (int64)0);
|
||||
while (setKeyPool.size() < nTargetSize+1)
|
||||
{
|
||||
int64 nEnd = 1;
|
||||
if (!setKeyPool.empty())
|
||||
nEnd = *(--setKeyPool.end()) + 1;
|
||||
if (!Write(make_pair(string("pool"), nEnd), CKeyPool(GenerateNewKey())))
|
||||
throw runtime_error("ReserveKeyFromKeyPool() : writing generated key failed");
|
||||
setKeyPool.insert(nEnd);
|
||||
printf("keypool added key %"PRI64d", size=%d\n", nEnd, setKeyPool.size());
|
||||
}
|
||||
|
||||
// Get the oldest key
|
||||
assert(!setKeyPool.empty());
|
||||
nIndex = *(setKeyPool.begin());
|
||||
setKeyPool.erase(setKeyPool.begin());
|
||||
if (!Read(make_pair(string("pool"), nIndex), keypool))
|
||||
throw runtime_error("ReserveKeyFromKeyPool() : read failed");
|
||||
if (!mapKeys.count(keypool.vchPubKey))
|
||||
throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool");
|
||||
assert(!keypool.vchPubKey.empty());
|
||||
printf("keypool reserve %"PRI64d"\n", nIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void CWalletDB::KeepKey(int64 nIndex)
|
||||
{
|
||||
// Remove from key pool
|
||||
CRITICAL_BLOCK(cs_main)
|
||||
CRITICAL_BLOCK(cs_mapWallet)
|
||||
{
|
||||
Erase(make_pair(string("pool"), nIndex));
|
||||
}
|
||||
printf("keypool keep %"PRI64d"\n", nIndex);
|
||||
}
|
||||
|
||||
void CWalletDB::ReturnKey(int64 nIndex)
|
||||
{
|
||||
// Return to key pool
|
||||
CRITICAL_BLOCK(cs_setKeyPool)
|
||||
setKeyPool.insert(nIndex);
|
||||
printf("keypool return %"PRI64d"\n", nIndex);
|
||||
}
|
||||
|
||||
vector<unsigned char> GetKeyFromKeyPool()
|
||||
{
|
||||
CWalletDB walletdb;
|
||||
int64 nIndex = 0;
|
||||
CKeyPool keypool;
|
||||
walletdb.ReserveKeyFromKeyPool(nIndex, keypool);
|
||||
walletdb.KeepKey(nIndex);
|
||||
return keypool.vchPubKey;
|
||||
}
|
||||
|
||||
int64 GetOldestKeyPoolTime()
|
||||
{
|
||||
CWalletDB walletdb;
|
||||
int64 nIndex = 0;
|
||||
CKeyPool keypool;
|
||||
walletdb.ReserveKeyFromKeyPool(nIndex, keypool);
|
||||
walletdb.ReturnKey(nIndex);
|
||||
return keypool.nTime;
|
||||
}
|
||||
|
||||
99
db.h
99
db.h
@@ -11,6 +11,8 @@ class CUser;
|
||||
class CReview;
|
||||
class CAddress;
|
||||
class CWalletTx;
|
||||
class CAccount;
|
||||
class CAccountingEntry;
|
||||
|
||||
extern map<string, string> mapAddressBook;
|
||||
extern CCriticalSection cs_mapAddressBook;
|
||||
@@ -24,6 +26,8 @@ extern DbEnv dbenv;
|
||||
|
||||
|
||||
extern void DBFlush(bool fShutdown);
|
||||
extern vector<unsigned char> GetKeyFromKeyPool();
|
||||
extern int64 GetOldestKeyPoolTime();
|
||||
|
||||
|
||||
|
||||
@@ -261,7 +265,7 @@ public:
|
||||
class CTxDB : public CDB
|
||||
{
|
||||
public:
|
||||
CTxDB(const char* pszMode="r+") : CDB(!fClient ? "blkindex.dat" : NULL, pszMode) { }
|
||||
CTxDB(const char* pszMode="r+") : CDB("blkindex.dat", pszMode) { }
|
||||
private:
|
||||
CTxDB(const CTxDB&);
|
||||
void operator=(const CTxDB&);
|
||||
@@ -298,6 +302,7 @@ private:
|
||||
void operator=(const CAddrDB&);
|
||||
public:
|
||||
bool WriteAddress(const CAddress& addr);
|
||||
bool EraseAddress(const CAddress& addr);
|
||||
bool LoadAddresses();
|
||||
};
|
||||
|
||||
@@ -308,10 +313,41 @@ bool LoadAddresses();
|
||||
|
||||
|
||||
|
||||
class CKeyPool
|
||||
{
|
||||
public:
|
||||
int64 nTime;
|
||||
vector<unsigned char> vchPubKey;
|
||||
|
||||
CKeyPool()
|
||||
{
|
||||
nTime = GetTime();
|
||||
}
|
||||
|
||||
CKeyPool(const vector<unsigned char>& vchPubKeyIn)
|
||||
{
|
||||
nTime = GetTime();
|
||||
vchPubKey = vchPubKeyIn;
|
||||
}
|
||||
|
||||
IMPLEMENT_SERIALIZE
|
||||
(
|
||||
if (!(nType & SER_GETHASH))
|
||||
READWRITE(nVersion);
|
||||
READWRITE(nTime);
|
||||
READWRITE(vchPubKey);
|
||||
)
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class CWalletDB : public CDB
|
||||
{
|
||||
public:
|
||||
CWalletDB(const char* pszMode="r+") : CDB("wallet.dat", pszMode) { }
|
||||
CWalletDB(const char* pszMode="r+") : CDB("wallet.dat", pszMode)
|
||||
{
|
||||
}
|
||||
private:
|
||||
CWalletDB(const CWalletDB&);
|
||||
void operator=(const CWalletDB&);
|
||||
@@ -395,7 +431,20 @@ public:
|
||||
return Write(make_pair(string("setting"), strKey), value);
|
||||
}
|
||||
|
||||
bool ReadAccount(const string& strAccount, CAccount& account);
|
||||
bool WriteAccount(const string& strAccount, const CAccount& account);
|
||||
bool WriteAccountingEntry(const string& strAccount, const CAccountingEntry& acentry);
|
||||
int64 GetAccountCreditDebit(const string& strAccount);
|
||||
void ListAccountCreditDebit(const string& strAccount, list<CAccountingEntry>& acentries);
|
||||
|
||||
bool LoadWallet();
|
||||
protected:
|
||||
void ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool);
|
||||
void KeepKey(int64 nIndex);
|
||||
static void ReturnKey(int64 nIndex);
|
||||
friend class CReserveKey;
|
||||
friend vector<unsigned char> GetKeyFromKeyPool();
|
||||
friend int64 GetOldestKeyPoolTime();
|
||||
};
|
||||
|
||||
bool LoadWallet(bool& fFirstRunRet);
|
||||
@@ -405,3 +454,49 @@ inline bool SetAddressBookName(const string& strAddress, const string& strName)
|
||||
{
|
||||
return CWalletDB().WriteName(strAddress, strName);
|
||||
}
|
||||
|
||||
class CReserveKey
|
||||
{
|
||||
protected:
|
||||
int64 nIndex;
|
||||
vector<unsigned char> vchPubKey;
|
||||
public:
|
||||
CReserveKey()
|
||||
{
|
||||
nIndex = -1;
|
||||
}
|
||||
|
||||
~CReserveKey()
|
||||
{
|
||||
if (!fShutdown)
|
||||
ReturnKey();
|
||||
}
|
||||
|
||||
vector<unsigned char> GetReservedKey()
|
||||
{
|
||||
if (nIndex == -1)
|
||||
{
|
||||
CKeyPool keypool;
|
||||
CWalletDB().ReserveKeyFromKeyPool(nIndex, keypool);
|
||||
vchPubKey = keypool.vchPubKey;
|
||||
}
|
||||
assert(!vchPubKey.empty());
|
||||
return vchPubKey;
|
||||
}
|
||||
|
||||
void KeepKey()
|
||||
{
|
||||
if (nIndex != -1)
|
||||
CWalletDB().KeepKey(nIndex);
|
||||
nIndex = -1;
|
||||
vchPubKey.clear();
|
||||
}
|
||||
|
||||
void ReturnKey()
|
||||
{
|
||||
if (nIndex != -1)
|
||||
CWalletDB::ReturnKey(nIndex);
|
||||
nIndex = -1;
|
||||
vchPubKey.clear();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#ifdef _WIN32_WINNT
|
||||
#undef _WIN32_WINNT
|
||||
#endif
|
||||
#define _WIN32_WINNT 0x0400
|
||||
#define _WIN32_WINNT 0x0500
|
||||
#ifdef _WIN32_IE
|
||||
#undef _WIN32_IE
|
||||
#endif
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <db_cxx.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include <limits.h>
|
||||
#include <float.h>
|
||||
@@ -70,6 +71,7 @@
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/interprocess/sync/file_lock.hpp>
|
||||
#include <boost/interprocess/sync/interprocess_mutex.hpp>
|
||||
#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
|
||||
#include <boost/date_time/gregorian/gregorian_types.hpp>
|
||||
@@ -99,6 +101,7 @@
|
||||
#include <net/if.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#endif
|
||||
#ifdef BSD
|
||||
#include <netinet/in.h>
|
||||
|
||||
100
init.cpp
100
init.cpp
@@ -10,7 +10,6 @@
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Shutdown
|
||||
@@ -57,6 +56,11 @@ void Shutdown(void* parg)
|
||||
}
|
||||
}
|
||||
|
||||
void HandleSIGTERM(int)
|
||||
{
|
||||
fRequestShutdown = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -130,6 +134,14 @@ bool AppInit2(int argc, char* argv[])
|
||||
#ifndef __WXMSW__
|
||||
umask(077);
|
||||
#endif
|
||||
#ifndef __WXMSW__
|
||||
// Clean shutdown on SIGTERM
|
||||
struct sigaction sa;
|
||||
sa.sa_handler = HandleSIGTERM;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = 0;
|
||||
sigaction(SIGTERM, &sa, NULL);
|
||||
#endif
|
||||
|
||||
//
|
||||
// Parameters
|
||||
@@ -153,17 +165,35 @@ bool AppInit2(int argc, char* argv[])
|
||||
" bitcoin [options] help \t\t " + _("List commands\n") +
|
||||
" bitcoin [options] help <command> \t\t " + _("Get help for a command\n") +
|
||||
_("Options:\n") +
|
||||
" -conf=<file> \t " + _("Specify configuration file (default: bitcoin.conf)\n") +
|
||||
" -gen \t " + _("Generate coins\n") +
|
||||
" -gen=0 \t " + _("Don't generate coins\n") +
|
||||
" -min \t " + _("Start minimized\n") +
|
||||
" -datadir=<dir> \t " + _("Specify data directory\n") +
|
||||
" -proxy=<ip:port>\t " + _("Connect through socks4 proxy\n") +
|
||||
" -addnode=<ip> \t " + _("Add a node to connect to\n") +
|
||||
" -connect=<ip> \t " + _("Connect only to the specified node\n") +
|
||||
" -server \t " + _("Accept command line and JSON-RPC commands\n") +
|
||||
" -daemon \t " + _("Run in the background as a daemon and accept commands\n") +
|
||||
" -? \t " + _("This help message\n");
|
||||
" -conf=<file> \t\t " + _("Specify configuration file (default: bitcoin.conf)\n") +
|
||||
" -gen \t\t " + _("Generate coins\n") +
|
||||
" -gen=0 \t\t " + _("Don't generate coins\n") +
|
||||
" -min \t\t " + _("Start minimized\n") +
|
||||
" -datadir=<dir> \t\t " + _("Specify data directory\n") +
|
||||
" -proxy=<ip:port> \t " + _("Connect through socks4 proxy\n") +
|
||||
" -addnode=<ip> \t " + _("Add a node to connect to\n") +
|
||||
" -connect=<ip> \t\t " + _("Connect only to the specified node\n") +
|
||||
" -paytxfee=<amt> \t " + _("Fee per KB to add to transactions you send\n") +
|
||||
" -server \t\t " + _("Accept command line and JSON-RPC commands\n") +
|
||||
" -daemon \t\t " + _("Run in the background as a daemon and accept commands\n") +
|
||||
" -testnet \t\t " + _("Use the test network\n") +
|
||||
" -rpcuser=<user> \t " + _("Username for JSON-RPC connections\n") +
|
||||
" -rpcpassword=<pw>\t " + _("Password for JSON-RPC connections\n") +
|
||||
" -rpcport=<port> \t\t " + _("Listen for JSON-RPC connections on <port>\n") +
|
||||
" -rpcallowip=<ip> \t\t " + _("Allow JSON-RPC connections from specified IP address\n") +
|
||||
" -rpcconnect=<ip> \t " + _("Send commands to node running on <ip>\n");
|
||||
|
||||
#ifdef USE_SSL
|
||||
strUsage += string() +
|
||||
_("\nSSL options: (see the Bitcoin Wiki for SSL setup instructions)\n") +
|
||||
" -rpcssl=1 \t " + _("Use OpenSSL (https) for JSON-RPC connections\n") +
|
||||
" -rpcsslcertificatchainfile=<file.cert>\t " + _("Server certificate file (default: server.cert)\n") +
|
||||
" -rpcsslprivatekeyfile=<file.pem> \t " + _("Server private key (default: server.pem)\n") +
|
||||
" -rpcsslciphers=<ciphers> \t " + _("Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)\n");
|
||||
#endif
|
||||
|
||||
strUsage += string() +
|
||||
" -? \t\t " + _("This help message\n");
|
||||
|
||||
#if defined(__WXMSW__) && defined(GUI)
|
||||
// Tabs make the columns line up in the message box
|
||||
@@ -176,11 +206,11 @@ bool AppInit2(int argc, char* argv[])
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mapArgs.count("-debug"))
|
||||
fDebug = true;
|
||||
fDebug = GetBoolArg("-debug");
|
||||
|
||||
if (mapArgs.count("-printtodebugger"))
|
||||
fPrintToDebugger = true;
|
||||
fPrintToDebugger = GetBoolArg("-printtodebugger");
|
||||
|
||||
fTestNet = GetBoolArg("-testnet");
|
||||
|
||||
if (fCommandLine)
|
||||
{
|
||||
@@ -191,7 +221,7 @@ bool AppInit2(int argc, char* argv[])
|
||||
if (!fDebug && !pszSetDataDir[0])
|
||||
ShrinkDebugFile();
|
||||
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
|
||||
printf("Bitcoin version %d.%d.%d%s beta\n", VERSION/10000, (VERSION/100)%100, VERSION%100, pszSubVer);
|
||||
printf("Bitcoin version %s%s beta\n", FormatVersion(VERSION).c_str(), pszSubVer);
|
||||
#ifdef GUI
|
||||
printf("OS version %s\n", ((string)wxGetOsDescription()).c_str());
|
||||
printf("System default language is %d %s\n", g_locale.GetSystemLanguage(), ((string)g_locale.GetSysName()).c_str());
|
||||
@@ -199,7 +229,7 @@ bool AppInit2(int argc, char* argv[])
|
||||
#endif
|
||||
printf("Default data directory %s\n", GetDefaultDataDir().c_str());
|
||||
|
||||
if (mapArgs.count("-loadblockindextest"))
|
||||
if (GetBoolArg("-loadblockindextest"))
|
||||
{
|
||||
CTxDB txdb("r");
|
||||
txdb.LoadBlockIndex();
|
||||
@@ -212,8 +242,7 @@ bool AppInit2(int argc, char* argv[])
|
||||
// Required to protect the database files if we're going to keep deleting log.*
|
||||
//
|
||||
#if defined(__WXMSW__) && defined(GUI)
|
||||
// todo: wxSingleInstanceChecker wasn't working on Linux, never deleted its lock file
|
||||
// maybe should go by whether successfully bind port 8333 instead
|
||||
// wxSingleInstanceChecker doesn't work on Linux
|
||||
wxString strMutexName = wxString("bitcoin_running.") + getenv("HOMEPATH");
|
||||
for (int i = 0; i < strMutexName.size(); i++)
|
||||
if (!isalnum(strMutexName[i]))
|
||||
@@ -225,7 +254,6 @@ bool AppInit2(int argc, char* argv[])
|
||||
unsigned int nStart = GetTime();
|
||||
loop
|
||||
{
|
||||
// TODO: find out how to do this in Linux, or replace with wxWidgets commands
|
||||
// Show the previous instance and exit
|
||||
HWND hwndPrev = FindWindowA("wxWindowClassNR", "Bitcoin");
|
||||
if (hwndPrev)
|
||||
@@ -249,8 +277,18 @@ bool AppInit2(int argc, char* argv[])
|
||||
}
|
||||
#endif
|
||||
|
||||
// Make sure only a single bitcoin process is using the data directory.
|
||||
string strLockFile = GetDataDir() + "/.lock";
|
||||
FILE* file = fopen(strLockFile.c_str(), "a"); // empty lock file; created if it doesn't exist.
|
||||
fclose(file);
|
||||
static boost::interprocess::file_lock lock(strLockFile.c_str());
|
||||
if (!lock.try_lock())
|
||||
{
|
||||
wxMessageBox(strprintf(_("Cannot obtain a lock on data directory %s. Bitcoin is probably already running."), GetDataDir().c_str()), "Bitcoin");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Bind to the port early so we can tell if another instance is already running.
|
||||
// This is a backup to wxSingleInstanceChecker, which doesn't work on Linux.
|
||||
string strErrors;
|
||||
if (!BindListenPort(strErrors))
|
||||
{
|
||||
@@ -297,7 +335,7 @@ bool AppInit2(int argc, char* argv[])
|
||||
|
||||
if (!strErrors.empty())
|
||||
{
|
||||
wxMessageBox(strErrors, "Bitcoin");
|
||||
wxMessageBox(strErrors, "Bitcoin", wxOK | wxICON_ERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -307,7 +345,7 @@ bool AppInit2(int argc, char* argv[])
|
||||
//
|
||||
// Parameters
|
||||
//
|
||||
if (mapArgs.count("-printblockindex") || mapArgs.count("-printblocktree"))
|
||||
if (GetBoolArg("-printblockindex") || GetBoolArg("-printblocktree"))
|
||||
{
|
||||
PrintBlockTree();
|
||||
return false;
|
||||
@@ -336,13 +374,7 @@ bool AppInit2(int argc, char* argv[])
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mapArgs.count("-gen"))
|
||||
{
|
||||
if (mapArgs["-gen"].empty())
|
||||
fGenerateBitcoins = true;
|
||||
else
|
||||
fGenerateBitcoins = (atoi(mapArgs["-gen"].c_str()) != 0);
|
||||
}
|
||||
fGenerateBitcoins = GetBoolArg("-gen");
|
||||
|
||||
if (mapArgs.count("-proxy"))
|
||||
{
|
||||
@@ -373,8 +405,8 @@ bool AppInit2(int argc, char* argv[])
|
||||
wxMessageBox(_("Invalid amount for -paytxfee=<amount>"), "Bitcoin");
|
||||
return false;
|
||||
}
|
||||
if (nTransactionFee > 1 * COIN)
|
||||
wxMessageBox(_("Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction."), "Bitcoin");
|
||||
if (nTransactionFee > 0.25 * COIN)
|
||||
wxMessageBox(_("Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction."), "Bitcoin", wxOK | wxICON_EXCLAMATION);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -393,7 +425,7 @@ bool AppInit2(int argc, char* argv[])
|
||||
if (!CreateThread(StartNode, NULL))
|
||||
wxMessageBox("Error: CreateThread(StartNode) failed", "Bitcoin");
|
||||
|
||||
if (mapArgs.count("-server") || fDaemon)
|
||||
if (GetBoolArg("-server") || fDaemon)
|
||||
CreateThread(ThreadRPCServer, NULL);
|
||||
|
||||
#if defined(__WXMSW__) && defined(GUI)
|
||||
|
||||
143
irc.cpp
143
irc.cpp
@@ -6,6 +6,9 @@
|
||||
|
||||
int nGotIRCAddresses = 0;
|
||||
|
||||
void ThreadIRCSeed2(void* parg);
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma pack(push, 1)
|
||||
@@ -81,18 +84,31 @@ bool RecvLine(SOCKET hSocket, string& strLine)
|
||||
}
|
||||
else if (nBytes <= 0)
|
||||
{
|
||||
if (fShutdown)
|
||||
return false;
|
||||
if (nBytes < 0)
|
||||
{
|
||||
int nErr = WSAGetLastError();
|
||||
if (nErr == WSAEMSGSIZE)
|
||||
continue;
|
||||
if (nErr == WSAEWOULDBLOCK || nErr == WSAEINTR || nErr == WSAEINPROGRESS)
|
||||
{
|
||||
Sleep(10);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!strLine.empty())
|
||||
return true;
|
||||
// socket closed
|
||||
printf("IRC socket closed\n");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// socket error
|
||||
int nErr = WSAGetLastError();
|
||||
if (nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
|
||||
if (nBytes == 0)
|
||||
{
|
||||
// socket closed
|
||||
printf("IRC socket closed\n");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// socket error
|
||||
int nErr = WSAGetLastError();
|
||||
printf("IRC recv failed: %d\n", nErr);
|
||||
return false;
|
||||
}
|
||||
@@ -123,11 +139,12 @@ bool RecvLineIRC(SOCKET hSocket, string& strLine)
|
||||
}
|
||||
}
|
||||
|
||||
int RecvUntil(SOCKET hSocket, const char* psz1, const char* psz2=NULL, const char* psz3=NULL)
|
||||
int RecvUntil(SOCKET hSocket, const char* psz1, const char* psz2=NULL, const char* psz3=NULL, const char* psz4=NULL)
|
||||
{
|
||||
loop
|
||||
{
|
||||
string strLine;
|
||||
strLine.reserve(10000);
|
||||
if (!RecvLineIRC(hSocket, strLine))
|
||||
return 0;
|
||||
printf("IRC %s\n", strLine.c_str());
|
||||
@@ -137,6 +154,8 @@ int RecvUntil(SOCKET hSocket, const char* psz1, const char* psz2=NULL, const cha
|
||||
return 2;
|
||||
if (psz3 && strLine.find(psz3) != -1)
|
||||
return 3;
|
||||
if (psz4 && strLine.find(psz4) != -1)
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,13 +173,90 @@ bool Wait(int nSeconds)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RecvCodeLine(SOCKET hSocket, const char* psz1, string& strRet)
|
||||
{
|
||||
strRet.clear();
|
||||
loop
|
||||
{
|
||||
string strLine;
|
||||
if (!RecvLineIRC(hSocket, strLine))
|
||||
return false;
|
||||
|
||||
vector<string> vWords;
|
||||
ParseString(strLine, ' ', vWords);
|
||||
if (vWords.size() < 2)
|
||||
continue;
|
||||
|
||||
if (vWords[1] == psz1)
|
||||
{
|
||||
printf("IRC %s\n", strLine.c_str());
|
||||
strRet = strLine;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool GetIPFromIRC(SOCKET hSocket, string strMyName, unsigned int& ipRet)
|
||||
{
|
||||
Send(hSocket, strprintf("USERHOST %s\r", strMyName.c_str()).c_str());
|
||||
|
||||
string strLine;
|
||||
if (!RecvCodeLine(hSocket, "302", strLine))
|
||||
return false;
|
||||
|
||||
vector<string> vWords;
|
||||
ParseString(strLine, ' ', vWords);
|
||||
if (vWords.size() < 4)
|
||||
return false;
|
||||
|
||||
string str = vWords[3];
|
||||
if (str.rfind("@") == string::npos)
|
||||
return false;
|
||||
string strHost = str.substr(str.rfind("@")+1);
|
||||
|
||||
unsigned int a=0, b=0, c=0, d=0;
|
||||
if (sscanf(strHost.c_str(), "%u.%u.%u.%u", &a, &b, &c, &d) == 4 &&
|
||||
inet_addr(strHost.c_str()) != INADDR_NONE)
|
||||
{
|
||||
printf("GetIPFromIRC() userhost is IP %s\n", strHost.c_str());
|
||||
ipRet = CAddress(strHost).ip;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("GetIPFromIRC() got userhost %s\n", strHost.c_str());
|
||||
if (fUseProxy)
|
||||
return false;
|
||||
struct hostent* phostent = gethostbyname(strHost.c_str());
|
||||
if (!phostent || !phostent->h_addr_list || !phostent->h_addr_list[0])
|
||||
return false;
|
||||
ipRet = *(u_long*)phostent->h_addr_list[0];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ThreadIRCSeed(void* parg)
|
||||
{
|
||||
IMPLEMENT_RANDOMIZE_STACK(ThreadIRCSeed(parg));
|
||||
try
|
||||
{
|
||||
ThreadIRCSeed2(parg);
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
PrintExceptionContinue(&e, "ThreadIRCSeed()");
|
||||
} catch (...) {
|
||||
PrintExceptionContinue(NULL, "ThreadIRCSeed()");
|
||||
}
|
||||
printf("ThreadIRCSeed exiting\n");
|
||||
}
|
||||
|
||||
void ThreadIRCSeed2(void* parg)
|
||||
{
|
||||
if (mapArgs.count("-connect"))
|
||||
return;
|
||||
if (mapArgs.count("-noirc"))
|
||||
if (GetBoolArg("-noirc"))
|
||||
return;
|
||||
printf("ThreadIRCSeed started\n");
|
||||
int nErrorWait = 10;
|
||||
@@ -191,7 +287,7 @@ void ThreadIRCSeed(void* parg)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!RecvUntil(hSocket, "Found your hostname", "using your IP address instead", "Couldn't look up your hostname"))
|
||||
if (!RecvUntil(hSocket, "Found your hostname", "using your IP address instead", "Couldn't look up your hostname", "ignoring hostname"))
|
||||
{
|
||||
closesocket(hSocket);
|
||||
hSocket = INVALID_SOCKET;
|
||||
@@ -231,11 +327,26 @@ void ThreadIRCSeed(void* parg)
|
||||
}
|
||||
Sleep(500);
|
||||
|
||||
Send(hSocket, "JOIN #bitcoin\r");
|
||||
Send(hSocket, "WHO #bitcoin\r");
|
||||
// Get my external IP from IRC server
|
||||
CAddress addrFromIRC;
|
||||
if (GetIPFromIRC(hSocket, strMyName, addrFromIRC.ip))
|
||||
{
|
||||
// Just using it as a backup for now
|
||||
printf("GetIPFromIRC() returned %s\n", addrFromIRC.ToStringIP().c_str());
|
||||
if (addrFromIRC.IsRoutable() && !fUseProxy && !addrLocalHost.IsRoutable())
|
||||
{
|
||||
addrLocalHost.ip = addrFromIRC.ip;
|
||||
strMyName = EncodeAddress(addrLocalHost);
|
||||
Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
Send(hSocket, fTestNet ? "JOIN #bitcoinTEST\r" : "JOIN #bitcoin\r");
|
||||
Send(hSocket, fTestNet ? "WHO #bitcoinTEST\r" : "WHO #bitcoin\r");
|
||||
|
||||
int64 nStart = GetTime();
|
||||
string strLine;
|
||||
strLine.reserve(10000);
|
||||
while (!fShutdown && RecvLineIRC(hSocket, strLine))
|
||||
{
|
||||
if (strLine.empty() || strLine.size() > 900 || strLine[0] != ':')
|
||||
@@ -271,8 +382,8 @@ void ThreadIRCSeed(void* parg)
|
||||
CAddress addr;
|
||||
if (DecodeAddress(pszName, addr))
|
||||
{
|
||||
addr.nTime = GetAdjustedTime() - 51 * 60;
|
||||
if (AddAddress(addr))
|
||||
addr.nTime = GetAdjustedTime();
|
||||
if (AddAddress(addr, 51 * 60))
|
||||
printf("IRC got new address\n");
|
||||
nGotIRCAddresses++;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -321,8 +321,8 @@ msgstr "Beim schließen &Minimieren"
|
||||
|
||||
#: ../../../ui.cpp:1595
|
||||
#, c-format
|
||||
msgid "version 0.%d.%d beta"
|
||||
msgstr "Version 0.%d.%d Beta"
|
||||
msgid "version %s%s beta"
|
||||
msgstr "Version %s%s Beta"
|
||||
|
||||
#: ../../../ui.cpp:1681
|
||||
msgid "Will appear as \"From: Unknown\""
|
||||
|
||||
Binary file not shown.
@@ -350,8 +350,8 @@ msgstr "&Minimizar al cerrar"
|
||||
|
||||
#: ../../../ui.cpp:1610
|
||||
#, c-format
|
||||
msgid "version %d.%d.%d beta"
|
||||
msgstr "version %d.%d.%d beta"
|
||||
msgid "version %s%s beta"
|
||||
msgstr "version %s%s beta"
|
||||
|
||||
#: ../../../ui.cpp:1696
|
||||
msgid "Will appear as \"From: Unknown\""
|
||||
|
||||
Binary file not shown.
@@ -351,8 +351,8 @@ msgstr "&Réduire à la fermeture"
|
||||
|
||||
#: ../../../ui.cpp:1610
|
||||
#, c-format
|
||||
msgid "version %d.%d.%d beta"
|
||||
msgstr "version %d.%d.%d beta"
|
||||
msgid "version %s%s beta"
|
||||
msgstr "version %s%s beta"
|
||||
|
||||
#: ../../../ui.cpp:1696
|
||||
msgid "Will appear as \"From: Unknown\""
|
||||
|
||||
Binary file not shown.
@@ -319,8 +319,8 @@ msgstr "&Minimizza se chiuso"
|
||||
|
||||
#: ../../../ui.cpp:1595
|
||||
#, c-format
|
||||
msgid "version 0.%d.%d beta"
|
||||
msgstr "versione 0.%d.%d beta"
|
||||
msgid "version %s%s beta"
|
||||
msgstr "versione %s%s beta"
|
||||
|
||||
#: ../../../ui.cpp:1681
|
||||
msgid "Will appear as \"From: Unknown\""
|
||||
|
||||
Binary file not shown.
@@ -320,8 +320,8 @@ msgstr "&Minimalizeer bij sluiten"
|
||||
|
||||
#: ../../../ui.cpp:1595
|
||||
#, c-format
|
||||
msgid "version 0.%d.%d beta"
|
||||
msgstr "versie 0.%d.%d beta"
|
||||
msgid "version %s%s beta"
|
||||
msgstr "versie %s%s beta"
|
||||
|
||||
#: ../../../ui.cpp:1681
|
||||
msgid "Will appear as \"From: Unknown\""
|
||||
|
||||
Binary file not shown.
@@ -319,8 +319,8 @@ msgstr "&Minimizar ao fechar"
|
||||
|
||||
#: ../../../ui.cpp:1595
|
||||
#, c-format
|
||||
msgid "version 0.%d.%d beta"
|
||||
msgstr "versão 0.%d.%d beta"
|
||||
msgid "version %s%s beta"
|
||||
msgstr "versão %s%s beta"
|
||||
|
||||
#: ../../../ui.cpp:1681
|
||||
msgid "Will appear as \"From: Unknown\""
|
||||
|
||||
BIN
locale/ru/LC_MESSAGES/bitcoin.mo
Normal file
BIN
locale/ru/LC_MESSAGES/bitcoin.mo
Normal file
Binary file not shown.
895
locale/ru/LC_MESSAGES/bitcoin.po
Normal file
895
locale/ru/LC_MESSAGES/bitcoin.po
Normal file
@@ -0,0 +1,895 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2010-10-05 10:53+0300\n"
|
||||
"PO-Revision-Date: 2010-10-05 11:43+0300\n"
|
||||
"Last-Translator: eurekafag\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Poedit-KeywordsList: _;gettext;gettext_noop\n"
|
||||
"X-Poedit-Basepath: .\n"
|
||||
"X-Poedit-SearchPath-0: ../../..\n"
|
||||
|
||||
#: ../../../init.cpp:162
|
||||
msgid "Usage:"
|
||||
msgstr "Использование"
|
||||
|
||||
#: ../../../init.cpp:164
|
||||
msgid "Send command to -server or bitcoind\n"
|
||||
msgstr "Отправить команду bitcoin, запущенному с -server\n"
|
||||
|
||||
#: ../../../init.cpp:165
|
||||
msgid "List commands\n"
|
||||
msgstr "Список команд\n"
|
||||
|
||||
#: ../../../init.cpp:166
|
||||
msgid "Get help for a command\n"
|
||||
msgstr "Получить помощь для команды\n"
|
||||
|
||||
#: ../../../init.cpp:167
|
||||
msgid "Options:\n"
|
||||
msgstr "Параметры:\n"
|
||||
|
||||
#: ../../../init.cpp:168
|
||||
msgid "Specify configuration file (default: bitcoin.conf)\n"
|
||||
msgstr "Укажите конфигурационный файл (по умолчанию: bitcoin.conf)\n"
|
||||
|
||||
#: ../../../init.cpp:169
|
||||
msgid "Generate coins\n"
|
||||
msgstr "Генерировать монеты\n"
|
||||
|
||||
#: ../../../init.cpp:170
|
||||
msgid "Don't generate coins\n"
|
||||
msgstr "Не генерировать монеты\n"
|
||||
|
||||
#: ../../../init.cpp:171
|
||||
msgid "Start minimized\n"
|
||||
msgstr "Запускать свёрнутым\n"
|
||||
|
||||
#: ../../../init.cpp:172
|
||||
msgid "Specify data directory\n"
|
||||
msgstr "Указать каталог данных\n"
|
||||
|
||||
#: ../../../init.cpp:173
|
||||
msgid "Connect through socks4 proxy\n"
|
||||
msgstr "Подключаться через socks4 прокси\n"
|
||||
|
||||
#: ../../../init.cpp:174
|
||||
msgid "Add a node to connect to\n"
|
||||
msgstr "Добавить узел для подключения\n"
|
||||
|
||||
#: ../../../init.cpp:175
|
||||
msgid "Connect only to the specified node\n"
|
||||
msgstr "Подключаться только к указанному узлу\n"
|
||||
|
||||
#: ../../../init.cpp:176
|
||||
msgid "Accept command line and JSON-RPC commands\n"
|
||||
msgstr "Принимать команды из командной строки и через JSON-RPC\n"
|
||||
|
||||
#: ../../../init.cpp:177
|
||||
msgid "Run in the background as a daemon and accept commands\n"
|
||||
msgstr "Запустить в фоне как демон и принимать команды\n"
|
||||
|
||||
#: ../../../init.cpp:178
|
||||
msgid "This help message\n"
|
||||
msgstr "Эта справка\n"
|
||||
|
||||
#: ../../../init.cpp:284
|
||||
msgid "Error loading addr.dat \n"
|
||||
msgstr "Ошибка загрузки addr.dat \n"
|
||||
|
||||
#: ../../../init.cpp:290
|
||||
msgid "Error loading blkindex.dat \n"
|
||||
msgstr "Ошибка загрузки blkindex.dat \n"
|
||||
|
||||
#: ../../../init.cpp:297
|
||||
msgid "Error loading wallet.dat \n"
|
||||
msgstr "Ошибка загрузки wallet.dat \n"
|
||||
|
||||
#: ../../../init.cpp:365
|
||||
msgid "Invalid -proxy address"
|
||||
msgstr "Неверный адрес -proxy"
|
||||
|
||||
#: ../../../init.cpp:385
|
||||
msgid "Invalid amount for -paytxfee=<amount>"
|
||||
msgstr "Неверное значение для -paytxfee=<amount>"
|
||||
|
||||
#: ../../../init.cpp:389
|
||||
msgid "Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction."
|
||||
msgstr "Внимание: -paytxfee установлено в очень большое значение. Это комиссия, которую вы будете платить при переводе."
|
||||
|
||||
#: ../../../main.cpp:1641
|
||||
msgid "Warning: Disk space is low "
|
||||
msgstr "Внимание: мало места на диске "
|
||||
|
||||
#: ../../../main.cpp:3505
|
||||
#, c-format
|
||||
msgid "Error: This is an oversized transaction that requires a transaction fee of %s "
|
||||
msgstr "Ошибка: этот перевод слишком большого размера, который требует комиссию %s "
|
||||
|
||||
#: ../../../main.cpp:3507
|
||||
msgid "Error: Transaction creation failed "
|
||||
msgstr "Ошибка: не удалось создать перевод "
|
||||
|
||||
#: ../../../main.cpp:3512
|
||||
#: ../../../ui.cpp:1964
|
||||
#: ../../../ui.cpp:1966
|
||||
#: ../../../ui.cpp:2107
|
||||
#: ../../../ui.cpp:2260
|
||||
msgid "Sending..."
|
||||
msgstr "Отправка..."
|
||||
|
||||
#: ../../../main.cpp:3516
|
||||
msgid "Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."
|
||||
msgstr "Перевод был отклонен. Это могло произойти, если некоторые из монет в вашем кошельке уже были потрачены, например, если вы использовали копию wallet.dat, и монеты были потрачены в копии, но не отмечены израсходованными здесь."
|
||||
|
||||
#: ../../../main.cpp:3528
|
||||
msgid "Invalid amount"
|
||||
msgstr "Неверное количество"
|
||||
|
||||
#: ../../../main.cpp:3530
|
||||
#: ../../../ui.cpp:2174
|
||||
#: ../../../ui.cpp:2245
|
||||
msgid "Insufficient funds"
|
||||
msgstr "Недостаточно средств"
|
||||
|
||||
#: ../../../main.cpp:3535
|
||||
msgid "Invalid bitcoin address"
|
||||
msgstr "Неверный адрес bitcoin"
|
||||
|
||||
#: ../../../rpc.cpp:963
|
||||
#: ../../../rpc.cpp:965
|
||||
#, c-format
|
||||
msgid "To use the %s option"
|
||||
msgstr "Чтобы использовать опцию %s"
|
||||
|
||||
#: ../../../rpc.cpp:967
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Warning: %s, you must set rpcpassword=<password>\n"
|
||||
"in the configuration file: %s\n"
|
||||
"If the file does not exist, create it with owner-readable-only file permissions.\n"
|
||||
msgstr ""
|
||||
"Внимание: %s, вы должны установить rpcpassword=<пароль>\n"
|
||||
"в конфигурационном файле: %s\n"
|
||||
"Если файл не существует, создайте его с правами \"чтение только владельцем\".\n"
|
||||
|
||||
#: ../../../rpc.cpp:1100
|
||||
#, c-format
|
||||
msgid ""
|
||||
"You must set rpcpassword=<password> in the configuration file:\n"
|
||||
"%s\n"
|
||||
"If the file does not exist, create it with owner-readable-only file permissions."
|
||||
msgstr ""
|
||||
"Вы должны установить rpcpassword=<пароль> в конфигурационном файле:\n"
|
||||
"%s\n"
|
||||
"Если файл не существует, создайте его с правами \"чтение только владельцем\"."
|
||||
|
||||
#: ../../../ui.cpp:202
|
||||
#, c-format
|
||||
msgid "This transaction is over the size limit. You can still send it for a fee of %s, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee?"
|
||||
msgstr "Этот перевод превышает допустимый лимит. Вы можете провести его с комиссией %s, которую получат узлы, обрабатывающие перевод, и поможет поддерживать сеть. Вы хотите заплатить комиссию?"
|
||||
|
||||
#: ../../../ui.cpp:301
|
||||
msgid "Status"
|
||||
msgstr "Статус"
|
||||
|
||||
#: ../../../ui.cpp:302
|
||||
msgid "Date"
|
||||
msgstr "Дата"
|
||||
|
||||
#: ../../../ui.cpp:303
|
||||
msgid "Description"
|
||||
msgstr "Описание"
|
||||
|
||||
#: ../../../ui.cpp:304
|
||||
msgid "Debit"
|
||||
msgstr "Дебет"
|
||||
|
||||
#: ../../../ui.cpp:305
|
||||
msgid "Credit"
|
||||
msgstr "Кредит"
|
||||
|
||||
#: ../../../ui.cpp:511
|
||||
#, c-format
|
||||
msgid "Open for %d blocks"
|
||||
msgstr "Открыто для %d блоков"
|
||||
|
||||
#: ../../../ui.cpp:513
|
||||
#, c-format
|
||||
msgid "Open until %s"
|
||||
msgstr "Открыто до %s"
|
||||
|
||||
#: ../../../ui.cpp:519
|
||||
#, c-format
|
||||
msgid "%d/offline?"
|
||||
msgstr "%d/оффлайн?"
|
||||
|
||||
#: ../../../ui.cpp:521
|
||||
#, c-format
|
||||
msgid "%d/unconfirmed"
|
||||
msgstr "%d/не подтверждено"
|
||||
|
||||
#: ../../../ui.cpp:523
|
||||
#, c-format
|
||||
msgid "%d confirmations"
|
||||
msgstr "%d подтверждений"
|
||||
|
||||
#: ../../../ui.cpp:608
|
||||
msgid "Generated"
|
||||
msgstr "Сгенерировано"
|
||||
|
||||
#: ../../../ui.cpp:616
|
||||
#, c-format
|
||||
msgid "Generated (%s matures in %d more blocks)"
|
||||
msgstr "Сгенерировано (%s станет доступно через %d блоков)"
|
||||
|
||||
#: ../../../ui.cpp:620
|
||||
msgid "Generated - Warning: This block was not received by any other nodes and will probably not be accepted!"
|
||||
msgstr "Сгенерировано - Внимание: этот блок не был получен ни одним узлом и, скорее всего, не будет принят!"
|
||||
|
||||
#: ../../../ui.cpp:624
|
||||
msgid "Generated (not accepted)"
|
||||
msgstr "Сгенерировано (не принято)"
|
||||
|
||||
#: ../../../ui.cpp:634
|
||||
msgid "From: "
|
||||
msgstr "От: "
|
||||
|
||||
#: ../../../ui.cpp:658
|
||||
msgid "Received with: "
|
||||
msgstr "Получено для: "
|
||||
|
||||
#: ../../../ui.cpp:704
|
||||
msgid "Payment to yourself"
|
||||
msgstr "Платёж самому себе"
|
||||
|
||||
#: ../../../ui.cpp:741
|
||||
msgid "To: "
|
||||
msgstr "Кому: "
|
||||
|
||||
#: ../../../ui.cpp:1049
|
||||
msgid " Generating"
|
||||
msgstr " Генерация"
|
||||
|
||||
#: ../../../ui.cpp:1051
|
||||
msgid "(not connected)"
|
||||
msgstr "(не подключен)"
|
||||
|
||||
#: ../../../ui.cpp:1054
|
||||
#, c-format
|
||||
msgid " %d connections %d blocks %d transactions"
|
||||
msgstr " %d подключений %d блоков %d переводов"
|
||||
|
||||
#: ../../../ui.cpp:1165
|
||||
#: ../../../ui.cpp:2560
|
||||
msgid "New Receiving Address"
|
||||
msgstr "Новый адрес получения"
|
||||
|
||||
#: ../../../ui.cpp:1166
|
||||
#: ../../../ui.cpp:2561
|
||||
msgid ""
|
||||
"You should use a new address for each payment you receive.\n"
|
||||
"\n"
|
||||
"Label"
|
||||
msgstr ""
|
||||
"Вы должны использовать новый адрес для каждого получаемого платежа.\n"
|
||||
"\n"
|
||||
"Метка"
|
||||
|
||||
#: ../../../ui.cpp:1235
|
||||
msgid "<b>Status:</b> "
|
||||
msgstr "<b>Статус:</b> "
|
||||
|
||||
#: ../../../ui.cpp:1240
|
||||
msgid ", has not been successfully broadcast yet"
|
||||
msgstr ", ещё не был успешно разослан"
|
||||
|
||||
#: ../../../ui.cpp:1242
|
||||
#, c-format
|
||||
msgid ", broadcast through %d node"
|
||||
msgstr ", рассылка через %d узел"
|
||||
|
||||
#: ../../../ui.cpp:1244
|
||||
#, c-format
|
||||
msgid ", broadcast through %d nodes"
|
||||
msgstr ", рассылка через %d узлов"
|
||||
|
||||
#: ../../../ui.cpp:1248
|
||||
msgid "<b>Date:</b> "
|
||||
msgstr "<b>Дата:</b> "
|
||||
|
||||
#: ../../../ui.cpp:1256
|
||||
msgid "<b>Source:</b> Generated<br>"
|
||||
msgstr "<b>Источник:</b> Сгенерировано<br>"
|
||||
|
||||
#: ../../../ui.cpp:1262
|
||||
#: ../../../ui.cpp:1280
|
||||
msgid "<b>From:</b> "
|
||||
msgstr "<b>От:</b> "
|
||||
|
||||
#: ../../../ui.cpp:1280
|
||||
msgid "unknown"
|
||||
msgstr "аноним"
|
||||
|
||||
#: ../../../ui.cpp:1281
|
||||
#: ../../../ui.cpp:1305
|
||||
#: ../../../ui.cpp:1364
|
||||
msgid "<b>To:</b> "
|
||||
msgstr "<b>Кому:</b> "
|
||||
|
||||
#: ../../../ui.cpp:1284
|
||||
msgid " (yours, label: "
|
||||
msgstr " (ваш, метка: "
|
||||
|
||||
#: ../../../ui.cpp:1286
|
||||
msgid " (yours)"
|
||||
msgstr " (ваш)"
|
||||
|
||||
#: ../../../ui.cpp:1323
|
||||
#: ../../../ui.cpp:1335
|
||||
#: ../../../ui.cpp:1398
|
||||
msgid "<b>Credit:</b> "
|
||||
msgstr "<b>Кредит:</b> "
|
||||
|
||||
#: ../../../ui.cpp:1325
|
||||
#, c-format
|
||||
msgid "(%s matures in %d more blocks)"
|
||||
msgstr "(%s станет доступно через %d блоков)"
|
||||
|
||||
#: ../../../ui.cpp:1327
|
||||
msgid "(not accepted)"
|
||||
msgstr "(не принято)"
|
||||
|
||||
#: ../../../ui.cpp:1372
|
||||
#: ../../../ui.cpp:1395
|
||||
msgid "<b>Debit:</b> "
|
||||
msgstr "<b>Дебет:</b> "
|
||||
|
||||
#: ../../../ui.cpp:1386
|
||||
msgid "<b>Transaction fee:</b> "
|
||||
msgstr "<b>Комиссия:</b> "
|
||||
|
||||
#: ../../../ui.cpp:1402
|
||||
msgid "<b>Net amount:</b> "
|
||||
msgstr "<b>Количество сети:</b> "
|
||||
|
||||
#: ../../../ui.cpp:1409
|
||||
msgid "Message:"
|
||||
msgstr "Сообщение:"
|
||||
|
||||
#: ../../../ui.cpp:1412
|
||||
msgid "Generated coins must wait 120 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, it will change to \"not accepted\" and not be spendable. This may occasionally happen if another node generates a block within a few seconds of yours."
|
||||
msgstr "Сгенерированные монеты должны ждать 120 блоков, прежде чем они могут быть потрачены. Когда вы сгенерировали этот блок, он был разослан в сети для добавления в цепь блоков. Если не удалось добавить этот блок в цепь, он будет обозначен как \"не принятый\" и не может быть потрачен. Такое может случиться, если другой узел сгенерировал блок через несколько секунд после вас."
|
||||
|
||||
#: ../../../ui.cpp:1593
|
||||
msgid "Cannot write autostart/bitcoin.desktop file"
|
||||
msgstr "Не удаётся записать файл autostart/bitcoin.desktop"
|
||||
|
||||
#: ../../../ui.cpp:1629
|
||||
msgid "Main"
|
||||
msgstr "Основные"
|
||||
|
||||
#: ../../../ui.cpp:1634
|
||||
msgid "&Start Bitcoin on window system startup"
|
||||
msgstr "&Запускать Bitcoin при запуске оконной системы"
|
||||
|
||||
#: ../../../ui.cpp:1641
|
||||
msgid "&Minimize on close"
|
||||
msgstr "&Сворачивать при закрытии"
|
||||
|
||||
#: ../../../ui.cpp:1798
|
||||
#, c-format
|
||||
msgid "version %s%s beta"
|
||||
msgstr "версия %s%s бета"
|
||||
|
||||
#: ../../../ui.cpp:1884
|
||||
msgid "n/a"
|
||||
msgstr "н/д"
|
||||
|
||||
#: ../../../ui.cpp:1885
|
||||
msgid "Can't include a message when sending to a Bitcoin address"
|
||||
msgstr "Не удаётся включить сообщение при отправке на адрес Bitcoin"
|
||||
|
||||
#: ../../../ui.cpp:1938
|
||||
msgid "Error in amount "
|
||||
msgstr "Ошибка в количестве "
|
||||
|
||||
#: ../../../ui.cpp:1938
|
||||
#: ../../../ui.cpp:1943
|
||||
#: ../../../ui.cpp:1948
|
||||
#: ../../../ui.cpp:1974
|
||||
#: ../../../uibase.cpp:59
|
||||
msgid "Send Coins"
|
||||
msgstr "Отправить монеты"
|
||||
|
||||
#: ../../../ui.cpp:1943
|
||||
msgid "Amount exceeds your balance "
|
||||
msgstr "Количество превышает ваш баланс "
|
||||
|
||||
#: ../../../ui.cpp:1948
|
||||
msgid "Total exceeds your balance when the "
|
||||
msgstr "Общая сумма превышает ваш баланс, когда "
|
||||
|
||||
#: ../../../ui.cpp:1948
|
||||
msgid " transaction fee is included "
|
||||
msgstr " комиссия включена "
|
||||
|
||||
#: ../../../ui.cpp:1964
|
||||
msgid "Payment sent "
|
||||
msgstr "Платёж отправлен "
|
||||
|
||||
#: ../../../ui.cpp:1974
|
||||
msgid "Invalid address "
|
||||
msgstr "Неверный адрес "
|
||||
|
||||
#: ../../../ui.cpp:2028
|
||||
#, c-format
|
||||
msgid "Sending %s to %s"
|
||||
msgstr "Отправка %s для %s"
|
||||
|
||||
#: ../../../ui.cpp:2101
|
||||
#: ../../../ui.cpp:2134
|
||||
msgid "CANCELLED"
|
||||
msgstr "ОТМЕНЕНО"
|
||||
|
||||
#: ../../../ui.cpp:2105
|
||||
msgid "Cancelled"
|
||||
msgstr "Отменено"
|
||||
|
||||
#: ../../../ui.cpp:2107
|
||||
msgid "Transfer cancelled "
|
||||
msgstr "Передача отменена "
|
||||
|
||||
#: ../../../ui.cpp:2160
|
||||
msgid "Error: "
|
||||
msgstr "Ошибка: "
|
||||
|
||||
#: ../../../ui.cpp:2179
|
||||
msgid "Connecting..."
|
||||
msgstr "Подключение..."
|
||||
|
||||
#: ../../../ui.cpp:2184
|
||||
msgid "Unable to connect"
|
||||
msgstr "Невозможно подключиться"
|
||||
|
||||
#: ../../../ui.cpp:2189
|
||||
msgid "Requesting public key..."
|
||||
msgstr "Запрос публичного ключа..."
|
||||
|
||||
#: ../../../ui.cpp:2201
|
||||
msgid "Received public key..."
|
||||
msgstr "Получен публичный ключ..."
|
||||
|
||||
#: ../../../ui.cpp:2215
|
||||
msgid "Recipient is not accepting transactions sent by IP address"
|
||||
msgstr "Получатель не принимает переводы на IP-адрес"
|
||||
|
||||
#: ../../../ui.cpp:2217
|
||||
msgid "Transfer was not accepted"
|
||||
msgstr "Передача не принята"
|
||||
|
||||
#: ../../../ui.cpp:2226
|
||||
msgid "Invalid response received"
|
||||
msgstr "Получен неверный отклик"
|
||||
|
||||
#: ../../../ui.cpp:2241
|
||||
msgid "Creating transaction..."
|
||||
msgstr "Создание перевода..."
|
||||
|
||||
#: ../../../ui.cpp:2253
|
||||
#, c-format
|
||||
msgid "This is an oversized transaction that requires a transaction fee of %s"
|
||||
msgstr "Это слишком большой перевод, который требует комиссию в размере %s"
|
||||
|
||||
#: ../../../ui.cpp:2255
|
||||
msgid "Transaction creation failed"
|
||||
msgstr "Не удалось создать перевод"
|
||||
|
||||
#: ../../../ui.cpp:2262
|
||||
msgid "Transaction aborted"
|
||||
msgstr "Перевод прерван"
|
||||
|
||||
#: ../../../ui.cpp:2270
|
||||
msgid "Lost connection, transaction cancelled"
|
||||
msgstr "Соединение разорвано, перевод отменён"
|
||||
|
||||
#: ../../../ui.cpp:2286
|
||||
msgid "Sending payment..."
|
||||
msgstr "Отправка платежа..."
|
||||
|
||||
#: ../../../ui.cpp:2292
|
||||
msgid "The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."
|
||||
msgstr "Перевод был отклонён. Это могло произойти, если некоторые из монет в вашем кошельке уже были потрачены, например, если вы использовали копию wallet.dat, и монеты были потрачены в копии, но не отмечены израсходованными здесь."
|
||||
|
||||
#: ../../../ui.cpp:2301
|
||||
msgid "Waiting for confirmation..."
|
||||
msgstr "Ожидание подтверждения..."
|
||||
|
||||
#: ../../../ui.cpp:2319
|
||||
msgid ""
|
||||
"The payment was sent, but the recipient was unable to verify it.\n"
|
||||
"The transaction is recorded and will credit to the recipient,\n"
|
||||
"but the comment information will be blank."
|
||||
msgstr ""
|
||||
"Платёж был отправлен, но получатель не смог проверить его.\n"
|
||||
"Перевод был записан и будет начислен получателю,\n"
|
||||
"но поле комментария будет пустое."
|
||||
|
||||
#: ../../../ui.cpp:2328
|
||||
msgid "Payment was sent, but an invalid response was received"
|
||||
msgstr "Платёж отправлен, но был получен неверный отклик"
|
||||
|
||||
#: ../../../ui.cpp:2334
|
||||
msgid "Payment completed"
|
||||
msgstr "Платёж проведён"
|
||||
|
||||
#: ../../../ui.cpp:2365
|
||||
#: ../../../ui.cpp:2511
|
||||
#: ../../../ui.cpp:2548
|
||||
msgid "Name"
|
||||
msgstr "Имя"
|
||||
|
||||
#: ../../../ui.cpp:2366
|
||||
#: ../../../ui.cpp:2511
|
||||
#: ../../../ui.cpp:2548
|
||||
msgid "Address"
|
||||
msgstr "Адрес"
|
||||
|
||||
#: ../../../ui.cpp:2368
|
||||
#: ../../../ui.cpp:2523
|
||||
msgid "Label"
|
||||
msgstr "Метка"
|
||||
|
||||
#: ../../../ui.cpp:2369
|
||||
#: ../../../uibase.cpp:902
|
||||
msgid "Bitcoin Address"
|
||||
msgstr "Адрес Bitcoin"
|
||||
|
||||
#: ../../../ui.cpp:2493
|
||||
msgid "This is one of your own addresses for receiving payments and cannot be entered in the address book. "
|
||||
msgstr "Это один из ваших собственных адресов для получения платежей, он не может быть внесён в адресную книгу. "
|
||||
|
||||
#: ../../../ui.cpp:2511
|
||||
#: ../../../ui.cpp:2517
|
||||
msgid "Edit Address"
|
||||
msgstr "Правка адреса"
|
||||
|
||||
#: ../../../ui.cpp:2523
|
||||
msgid "Edit Address Label"
|
||||
msgstr "Правка метки адреса"
|
||||
|
||||
#: ../../../ui.cpp:2548
|
||||
#: ../../../ui.cpp:2554
|
||||
msgid "Add Address"
|
||||
msgstr "Добавить адрес"
|
||||
|
||||
#: ../../../ui.cpp:2630
|
||||
msgid "Bitcoin"
|
||||
msgstr "Bitcoin"
|
||||
|
||||
#: ../../../ui.cpp:2632
|
||||
msgid "Bitcoin - Generating"
|
||||
msgstr "Bitcoin - Генерация"
|
||||
|
||||
#: ../../../ui.cpp:2634
|
||||
msgid "Bitcoin - (not connected)"
|
||||
msgstr "Bitcoin - (не подключен)"
|
||||
|
||||
#: ../../../ui.cpp:2711
|
||||
msgid "&Open Bitcoin"
|
||||
msgstr "&Открыть Bitcoin"
|
||||
|
||||
#: ../../../ui.cpp:2712
|
||||
msgid "O&ptions..."
|
||||
msgstr "О&пции..."
|
||||
|
||||
#: ../../../ui.cpp:2713
|
||||
#: ../../../uibase.cpp:32
|
||||
msgid "&Generate Coins"
|
||||
msgstr "&Генерировать монеты"
|
||||
|
||||
#: ../../../ui.cpp:2716
|
||||
#: ../../../uibase.cpp:25
|
||||
msgid "E&xit"
|
||||
msgstr "&Выход"
|
||||
|
||||
#: ../../../ui.cpp:2931
|
||||
msgid "Program has crashed and will terminate. "
|
||||
msgstr "Сбой программы, завершение. "
|
||||
|
||||
#: ../../../uibase.cpp:28
|
||||
msgid "&File"
|
||||
msgstr "&Файл"
|
||||
|
||||
#: ../../../uibase.cpp:36
|
||||
msgid "&Your Receiving Addresses..."
|
||||
msgstr "&Ваши адреса получения..."
|
||||
|
||||
#: ../../../uibase.cpp:40
|
||||
msgid "&Options..."
|
||||
msgstr "&Опции"
|
||||
|
||||
#: ../../../uibase.cpp:43
|
||||
msgid "&Settings"
|
||||
msgstr "&Настройки"
|
||||
|
||||
#: ../../../uibase.cpp:47
|
||||
msgid "&About..."
|
||||
msgstr "&О программе..."
|
||||
|
||||
#: ../../../uibase.cpp:50
|
||||
msgid "&Help"
|
||||
msgstr "&Справка"
|
||||
|
||||
#: ../../../uibase.cpp:60
|
||||
msgid "Address Book"
|
||||
msgstr "Адресная книга"
|
||||
|
||||
#: ../../../uibase.cpp:75
|
||||
msgid "Your Bitcoin Address:"
|
||||
msgstr "Ваш адрес Bitcoin:"
|
||||
|
||||
#: ../../../uibase.cpp:82
|
||||
msgid " &New... "
|
||||
msgstr " &Новый... "
|
||||
|
||||
#: ../../../uibase.cpp:85
|
||||
#: ../../../uibase.cpp:845
|
||||
#: ../../../uibase.cpp:948
|
||||
msgid " &Copy to Clipboard "
|
||||
msgstr " &Копировать в буфер обмена "
|
||||
|
||||
#: ../../../uibase.cpp:99
|
||||
msgid "Balance:"
|
||||
msgstr "Баланс:"
|
||||
|
||||
#: ../../../uibase.cpp:115
|
||||
msgid " All"
|
||||
msgstr " Все"
|
||||
|
||||
#: ../../../uibase.cpp:115
|
||||
msgid " Sent"
|
||||
msgstr " Отправленные"
|
||||
|
||||
#: ../../../uibase.cpp:115
|
||||
msgid " Received"
|
||||
msgstr " Полученные"
|
||||
|
||||
#: ../../../uibase.cpp:115
|
||||
msgid " In Progress"
|
||||
msgstr " В процессе"
|
||||
|
||||
#: ../../../uibase.cpp:136
|
||||
msgid "All Transactions"
|
||||
msgstr "Все переводы"
|
||||
|
||||
#: ../../../uibase.cpp:147
|
||||
msgid "Sent/Received"
|
||||
msgstr "Отправленные/Полученные"
|
||||
|
||||
#: ../../../uibase.cpp:158
|
||||
msgid "Sent"
|
||||
msgstr "Отправленные"
|
||||
|
||||
#: ../../../uibase.cpp:169
|
||||
msgid "Received"
|
||||
msgstr "Полученные"
|
||||
|
||||
#: ../../../uibase.cpp:312
|
||||
#: ../../../uibase.cpp:473
|
||||
#: ../../../uibase.cpp:574
|
||||
#: ../../../uibase.cpp:787
|
||||
#: ../../../uibase.cpp:848
|
||||
#: ../../../uibase.cpp:957
|
||||
#: ../../../uibase.cpp:1046
|
||||
msgid "OK"
|
||||
msgstr "ОК"
|
||||
|
||||
#: ../../../uibase.cpp:355
|
||||
msgid "Optional transaction fee you give to the nodes that process your transactions."
|
||||
msgstr "Необязательная комиссия, которую вы даёте узлам, проводящим ваш перевод."
|
||||
|
||||
#: ../../../uibase.cpp:364
|
||||
msgid "Transaction fee:"
|
||||
msgstr "Комиссия:"
|
||||
|
||||
#: ../../../uibase.cpp:380
|
||||
msgid "&Limit coin generation to"
|
||||
msgstr "&Ограничить генерацию монет до"
|
||||
|
||||
#: ../../../uibase.cpp:387
|
||||
msgid "processors"
|
||||
msgstr "процессоров"
|
||||
|
||||
#: ../../../uibase.cpp:393
|
||||
msgid "&Start Bitcoin on system startup"
|
||||
msgstr "&Запускать Bitcoin при старте системы"
|
||||
|
||||
#: ../../../uibase.cpp:397
|
||||
msgid "&Minimize to the tray instead of the taskbar"
|
||||
msgstr "&Сворачивать в трей вместо панели задач"
|
||||
|
||||
#: ../../../uibase.cpp:401
|
||||
msgid "M&inimize to the tray on close"
|
||||
msgstr "С&ворачивать в трей при закрытии"
|
||||
|
||||
#: ../../../uibase.cpp:408
|
||||
msgid "&Connect through socks4 proxy: "
|
||||
msgstr "&Подключаться через socks4 прокси: "
|
||||
|
||||
#: ../../../uibase.cpp:420
|
||||
msgid "Proxy &IP:"
|
||||
msgstr "IP п&рокси:"
|
||||
|
||||
#: ../../../uibase.cpp:428
|
||||
msgid " &Port:"
|
||||
msgstr " &Порт"
|
||||
|
||||
#: ../../../uibase.cpp:450
|
||||
msgid "// [don't translate] Test panel 2 for future expansion"
|
||||
msgstr ""
|
||||
|
||||
#: ../../../uibase.cpp:454
|
||||
msgid "// [don't translate] Let's not start multiple pages until the first page is filled up"
|
||||
msgstr ""
|
||||
|
||||
#: ../../../uibase.cpp:476
|
||||
#: ../../../uibase.cpp:729
|
||||
#: ../../../uibase.cpp:792
|
||||
#: ../../../uibase.cpp:851
|
||||
#: ../../../uibase.cpp:960
|
||||
#: ../../../uibase.cpp:1049
|
||||
msgid "Cancel"
|
||||
msgstr "Отмена"
|
||||
|
||||
#: ../../../uibase.cpp:479
|
||||
msgid "&Apply"
|
||||
msgstr "&Применить"
|
||||
|
||||
#: ../../../uibase.cpp:540
|
||||
msgid "Bitcoin "
|
||||
msgstr "Bitcoin "
|
||||
|
||||
#: ../../../uibase.cpp:546
|
||||
msgid "version"
|
||||
msgstr "версия"
|
||||
|
||||
#: ../../../uibase.cpp:557
|
||||
msgid ""
|
||||
"Copyright (c) 2009-2010 Satoshi Nakamoto.\n"
|
||||
"\n"
|
||||
"This is experimental software.\n"
|
||||
"\n"
|
||||
"Distributed under the MIT/X11 software license, see the accompanying file \n"
|
||||
"license.txt or http://www.opensource.org/licenses/mit-license.php.\n"
|
||||
"\n"
|
||||
"This product includes software developed by the OpenSSL Project for use in the \n"
|
||||
"OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by \n"
|
||||
"Eric Young (eay@cryptsoft.com)."
|
||||
msgstr ""
|
||||
"Все права защищены (c) 2009-2010 Satoshi Nakamoto.\n"
|
||||
"\n"
|
||||
"Это экспериментальное ПО.\n"
|
||||
"\n"
|
||||
"Распространяется под лицензией MIT/X11, см. файл\n"
|
||||
"license.txt или http://www.opensource.org/licenses/mit-license.php.\n"
|
||||
"\n"
|
||||
"Этот продукт включает ПО, разработанное проектом OpenSSL для использования в\n"
|
||||
"OpenSSL Toolkit (http://www.openssl.org/), и криптографическое ПО, написанное\n"
|
||||
"Eric Young (eay@cryptsoft.com)."
|
||||
|
||||
#: ../../../uibase.cpp:613
|
||||
msgid "Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) or IP address (e.g. 123.45.6.7)"
|
||||
msgstr "Введите адрес Bitcoin (напр. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) или IP адрес (напр. 123.45.6.7)"
|
||||
|
||||
#: ../../../uibase.cpp:627
|
||||
msgid "Pay &To:"
|
||||
msgstr "&Кому:"
|
||||
|
||||
#: ../../../uibase.cpp:642
|
||||
msgid "&Paste"
|
||||
msgstr "&Вставить"
|
||||
|
||||
#: ../../../uibase.cpp:645
|
||||
msgid " Address &Book..."
|
||||
msgstr " А&дресная книга..."
|
||||
|
||||
#: ../../../uibase.cpp:652
|
||||
msgid "&Amount:"
|
||||
msgstr "К&оличество:"
|
||||
|
||||
#: ../../../uibase.cpp:662
|
||||
msgid "T&ransfer:"
|
||||
msgstr "&Передача:"
|
||||
|
||||
#: ../../../uibase.cpp:668
|
||||
msgid " Standard"
|
||||
msgstr " Стандарт"
|
||||
|
||||
#: ../../../uibase.cpp:690
|
||||
msgid "&From:"
|
||||
msgstr "О&т:"
|
||||
|
||||
#: ../../../uibase.cpp:707
|
||||
msgid "&Message:"
|
||||
msgstr "&Сообщение:"
|
||||
|
||||
#: ../../../uibase.cpp:724
|
||||
msgid "&Send"
|
||||
msgstr "Отп&равить"
|
||||
|
||||
#: ../../../uibase.cpp:776
|
||||
msgid ""
|
||||
"\n"
|
||||
"\n"
|
||||
"Connecting..."
|
||||
msgstr ""
|
||||
"\n"
|
||||
"\n"
|
||||
"Подключение..."
|
||||
|
||||
#: ../../../uibase.cpp:826
|
||||
msgid "These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. The highlighted address is displayed in the main window."
|
||||
msgstr "Это ваши адреса для получения платежей. Вы можете использовать разные для каждого отправителя, чтобы отслеживать, кто вам платит. Выделенный адрес отображается в главном окне."
|
||||
|
||||
#: ../../../uibase.cpp:839
|
||||
#: ../../../uibase.cpp:951
|
||||
msgid "&Edit..."
|
||||
msgstr "&Правка..."
|
||||
|
||||
#: ../../../uibase.cpp:842
|
||||
#: ../../../uibase.cpp:954
|
||||
msgid " &New Address... "
|
||||
msgstr " &Новый адрес... "
|
||||
|
||||
#: ../../../uibase.cpp:914
|
||||
msgid "Sending"
|
||||
msgstr "Отправка"
|
||||
|
||||
#: ../../../uibase.cpp:922
|
||||
msgid "These are your Bitcoin addresses for receiving payments. You can give a different one to each sender to keep track of who is paying you. The highlighted address will be displayed in the main window."
|
||||
msgstr "Это ваши адреса для получения платежей. Вы можете использовать разные для каждого отправителя, чтобы отслеживать, кто вам платит. Выделенный адрес отображается в главном окне."
|
||||
|
||||
#: ../../../uibase.cpp:935
|
||||
msgid "Receiving"
|
||||
msgstr "Получение"
|
||||
|
||||
#: ../../../uibase.cpp:945
|
||||
msgid "&Delete"
|
||||
msgstr "&Удалить"
|
||||
|
||||
#: ../../../util.cpp:807
|
||||
msgid "Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly."
|
||||
msgstr "Внимание: пожалуйста, проверьте дату и время на вашем компьютере. Если часы идут неверно, Bitcoin не будет работать правильно."
|
||||
|
||||
#: ../../../uibase.h:149
|
||||
msgid "Transaction Details"
|
||||
msgstr "Подробности транзакции"
|
||||
|
||||
#: ../../../uibase.h:202
|
||||
msgid "Options"
|
||||
msgstr "Опции"
|
||||
|
||||
#: ../../../uibase.h:230
|
||||
msgid "About Bitcoin"
|
||||
msgstr "О Bitcoin"
|
||||
|
||||
#: ../../../uibase.h:340
|
||||
msgid "Your Bitcoin Addresses"
|
||||
msgstr "Ваш адрес Bitcoin"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "It's good policy to use a new address for each payment you receive.\n"
|
||||
#~ "\n"
|
||||
#~ "Label"
|
||||
#~ msgstr ""
|
||||
#~ "Неплохо будет использовать новый адрес для каждого получаемого платежа.\n"
|
||||
#~ "\n"
|
||||
#~ "Метка"
|
||||
|
||||
#~ msgid "Will appear as \"From: Unknown\""
|
||||
#~ msgstr "Будет отображаться как \"От: Аноним\""
|
||||
469
main.h
469
main.h
@@ -15,12 +15,13 @@ class CWalletTx;
|
||||
class CKeyItem;
|
||||
|
||||
static const unsigned int MAX_BLOCK_SIZE = 1000000;
|
||||
static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2;
|
||||
static const int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
|
||||
static const int64 COIN = 100000000;
|
||||
static const int64 CENT = 1000000;
|
||||
static const int64 MAX_MONEY = 21000000 * COIN;
|
||||
inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }
|
||||
static const int COINBASE_MATURITY = 100;
|
||||
static const CBigNum bnProofOfWorkLimit(~uint256(0) >> 32);
|
||||
|
||||
|
||||
|
||||
@@ -29,7 +30,8 @@ static const CBigNum bnProofOfWorkLimit(~uint256(0) >> 32);
|
||||
|
||||
extern CCriticalSection cs_main;
|
||||
extern map<uint256, CBlockIndex*> mapBlockIndex;
|
||||
extern const uint256 hashGenesisBlock;
|
||||
extern uint256 hashGenesisBlock;
|
||||
extern CBigNum bnProofOfWorkLimit;
|
||||
extern CBlockIndex* pindexGenesisBlock;
|
||||
extern int nBestHeight;
|
||||
extern CBigNum bnBestChainWork;
|
||||
@@ -74,13 +76,17 @@ bool ProcessMessages(CNode* pfrom);
|
||||
bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv);
|
||||
bool SendMessages(CNode* pto, bool fSendTrickle);
|
||||
int64 GetBalance();
|
||||
bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CKey& keyRet, int64& nFeeRequiredRet);
|
||||
bool CommitTransaction(CWalletTx& wtxNew, const CKey& key);
|
||||
bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet);
|
||||
bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey);
|
||||
bool BroadcastTransaction(CWalletTx& wtxNew);
|
||||
string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
|
||||
string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
|
||||
void GenerateBitcoins(bool fGenerate);
|
||||
void ThreadBitcoinMiner(void* parg);
|
||||
CBlock* CreateNewBlock(CReserveKey& reservekey);
|
||||
void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce, int64& nPrevTime);
|
||||
void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1);
|
||||
bool CheckWork(CBlock* pblock, CReserveKey& reservekey);
|
||||
void BitcoinMiner();
|
||||
bool CheckProofOfWork(uint256 hash, unsigned int nBits);
|
||||
bool IsInitialBlockDownload();
|
||||
@@ -193,7 +199,7 @@ public:
|
||||
|
||||
string ToString() const
|
||||
{
|
||||
return strprintf("COutPoint(%s, %d)", hash.ToString().substr(0,6).c_str(), n);
|
||||
return strprintf("COutPoint(%s, %d)", hash.ToString().substr(0,10).c_str(), n);
|
||||
}
|
||||
|
||||
void print() const
|
||||
@@ -266,7 +272,7 @@ public:
|
||||
str += strprintf("CTxIn(");
|
||||
str += prevout.ToString();
|
||||
if (prevout.IsNull())
|
||||
str += strprintf(", coinbase %s", HexStr(scriptSig.begin(), scriptSig.end(), false).c_str());
|
||||
str += strprintf(", coinbase %s", HexStr(scriptSig).c_str());
|
||||
else
|
||||
str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24).c_str());
|
||||
if (nSequence != UINT_MAX)
|
||||
@@ -339,9 +345,25 @@ public:
|
||||
{
|
||||
if (!MoneyRange(nValue))
|
||||
throw runtime_error("CTxOut::GetCredit() : value out of range");
|
||||
if (IsMine())
|
||||
return nValue;
|
||||
return 0;
|
||||
return (IsMine() ? nValue : 0);
|
||||
}
|
||||
|
||||
bool IsChange() const
|
||||
{
|
||||
// On a debit transaction, a txout that's mine but isn't in the address book is change
|
||||
vector<unsigned char> vchPubKey;
|
||||
if (ExtractPubKey(scriptPubKey, true, vchPubKey))
|
||||
CRITICAL_BLOCK(cs_mapAddressBook)
|
||||
if (!mapAddressBook.count(PubKeyToAddress(vchPubKey)))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
int64 GetChange() const
|
||||
{
|
||||
if (!MoneyRange(nValue))
|
||||
throw runtime_error("CTxOut::GetChange() : value out of range");
|
||||
return (IsChange() ? nValue : 0);
|
||||
}
|
||||
|
||||
friend bool operator==(const CTxOut& a, const CTxOut& b)
|
||||
@@ -359,7 +381,7 @@ public:
|
||||
{
|
||||
if (scriptPubKey.size() < 6)
|
||||
return "CTxOut(error)";
|
||||
return strprintf("CTxOut(nValue=%"PRI64d".%08"PRI64d", scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,24).c_str());
|
||||
return strprintf("CTxOut(nValue=%"PRI64d".%08"PRI64d", scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30).c_str());
|
||||
}
|
||||
|
||||
void print() const
|
||||
@@ -467,41 +489,24 @@ public:
|
||||
return (vin.size() == 1 && vin[0].prevout.IsNull());
|
||||
}
|
||||
|
||||
bool CheckTransaction() const
|
||||
int GetSigOpCount() const
|
||||
{
|
||||
// Basic checks that don't depend on any context
|
||||
if (vin.empty() || vout.empty())
|
||||
return error("CTransaction::CheckTransaction() : vin or vout empty");
|
||||
|
||||
// Size limits
|
||||
if (::GetSerializeSize(*this, SER_DISK) > MAX_SIZE)
|
||||
return error("CTransaction::CheckTransaction() : size limits failed");
|
||||
|
||||
// Check for negative or overflow output values
|
||||
int64 nValueOut = 0;
|
||||
int n = 0;
|
||||
foreach(const CTxIn& txin, vin)
|
||||
n += txin.scriptSig.GetSigOpCount();
|
||||
foreach(const CTxOut& txout, vout)
|
||||
{
|
||||
if (txout.nValue < 0)
|
||||
return error("CTransaction::CheckTransaction() : txout.nValue negative");
|
||||
if (txout.nValue > MAX_MONEY)
|
||||
return error("CTransaction::CheckTransaction() : txout.nValue too high");
|
||||
nValueOut += txout.nValue;
|
||||
if (!MoneyRange(nValueOut))
|
||||
return error("CTransaction::CheckTransaction() : txout total out of range");
|
||||
}
|
||||
|
||||
if (IsCoinBase())
|
||||
{
|
||||
if (vin[0].scriptSig.size() < 2 || vin[0].scriptSig.size() > 100)
|
||||
return error("CTransaction::CheckTransaction() : coinbase script size");
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach(const CTxIn& txin, vin)
|
||||
if (txin.prevout.IsNull())
|
||||
return error("CTransaction::CheckTransaction() : prevout is null");
|
||||
}
|
||||
n += txout.scriptPubKey.GetSigOpCount();
|
||||
return n;
|
||||
}
|
||||
|
||||
bool IsStandard() const
|
||||
{
|
||||
foreach(const CTxIn& txin, vin)
|
||||
if (!txin.scriptSig.IsPushOnly())
|
||||
return error("nonstandard txin: %s", txin.scriptSig.ToString().c_str());
|
||||
foreach(const CTxOut& txout, vout)
|
||||
if (!::IsStandard(txout.scriptPubKey))
|
||||
return error("nonstandard txout: %s", txout.scriptPubKey.ToString().c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -513,6 +518,11 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsFromMe() const
|
||||
{
|
||||
return (GetDebit() > 0);
|
||||
}
|
||||
|
||||
int64 GetDebit() const
|
||||
{
|
||||
int64 nDebit = 0;
|
||||
@@ -537,6 +547,20 @@ public:
|
||||
return nCredit;
|
||||
}
|
||||
|
||||
int64 GetChange() const
|
||||
{
|
||||
if (IsCoinBase())
|
||||
return 0;
|
||||
int64 nChange = 0;
|
||||
foreach(const CTxOut& txout, vout)
|
||||
{
|
||||
nChange += txout.GetChange();
|
||||
if (!MoneyRange(nChange))
|
||||
throw runtime_error("CTransaction::GetChange() : value out of range");
|
||||
}
|
||||
return nChange;
|
||||
}
|
||||
|
||||
int64 GetValueOut() const
|
||||
{
|
||||
int64 nValueOut = 0;
|
||||
@@ -549,20 +573,29 @@ public:
|
||||
return nValueOut;
|
||||
}
|
||||
|
||||
int64 GetMinFee(unsigned int nBlockSize=1) const
|
||||
int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=true) const
|
||||
{
|
||||
// Base fee is 1 cent per kilobyte
|
||||
unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK);
|
||||
unsigned int nNewBlockSize = nBlockSize + nBytes;
|
||||
int64 nMinFee = (1 + (int64)nBytes / 1000) * CENT;
|
||||
|
||||
// Transactions under 60K are free as long as block size is under 80K
|
||||
// (about 27,000bc if made of 50bc inputs)
|
||||
if (nBytes < 60000 && nBlockSize < 80000)
|
||||
nMinFee = 0;
|
||||
|
||||
// Transactions under 3K are free as long as block size is under 200K
|
||||
if (nBytes < 3000 && nBlockSize < 200000)
|
||||
nMinFee = 0;
|
||||
if (fAllowFree)
|
||||
{
|
||||
if (nBlockSize == 1)
|
||||
{
|
||||
// Transactions under 10K are free
|
||||
// (about 4500bc if made of 50bc inputs)
|
||||
if (nBytes < 10000)
|
||||
nMinFee = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Free transaction area
|
||||
if (nNewBlockSize < 27000)
|
||||
nMinFee = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// To limit dust spam, require a 0.01 fee if any output is less than 0.01
|
||||
if (nMinFee < CENT)
|
||||
@@ -570,11 +603,20 @@ public:
|
||||
if (txout.nValue < CENT)
|
||||
nMinFee = CENT;
|
||||
|
||||
// Raise the price as the block approaches full
|
||||
if (nBlockSize != 1 && nNewBlockSize >= MAX_BLOCK_SIZE_GEN/2)
|
||||
{
|
||||
if (nNewBlockSize >= MAX_BLOCK_SIZE_GEN)
|
||||
return MAX_MONEY;
|
||||
nMinFee *= MAX_BLOCK_SIZE_GEN / (MAX_BLOCK_SIZE_GEN - nNewBlockSize);
|
||||
}
|
||||
|
||||
if (!MoneyRange(nMinFee))
|
||||
nMinFee = MAX_MONEY;
|
||||
return nMinFee;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL)
|
||||
{
|
||||
CAutoFile filein = OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb");
|
||||
@@ -596,7 +638,6 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
friend bool operator==(const CTransaction& a, const CTransaction& b)
|
||||
{
|
||||
return (a.nVersion == b.nVersion &&
|
||||
@@ -615,7 +656,7 @@ public:
|
||||
{
|
||||
string str;
|
||||
str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%d, vout.size=%d, nLockTime=%d)\n",
|
||||
GetHash().ToString().substr(0,6).c_str(),
|
||||
GetHash().ToString().substr(0,10).c_str(),
|
||||
nVersion,
|
||||
vin.size(),
|
||||
vout.size(),
|
||||
@@ -633,22 +674,22 @@ public:
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool ReadFromDisk(CTxDB& txdb, COutPoint prevout, CTxIndex& txindexRet);
|
||||
bool ReadFromDisk(CTxDB& txdb, COutPoint prevout);
|
||||
bool ReadFromDisk(COutPoint prevout);
|
||||
bool DisconnectInputs(CTxDB& txdb);
|
||||
bool ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx,
|
||||
CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee=0);
|
||||
bool ClientConnectInputs();
|
||||
|
||||
bool AcceptTransaction(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL);
|
||||
|
||||
bool AcceptTransaction(bool fCheckInputs=true, bool* pfMissingInputs=NULL)
|
||||
bool CheckTransaction() const;
|
||||
bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL);
|
||||
bool AcceptToMemoryPool(bool fCheckInputs=true, bool* pfMissingInputs=NULL)
|
||||
{
|
||||
CTxDB txdb("r");
|
||||
return AcceptTransaction(txdb, fCheckInputs, pfMissingInputs);
|
||||
return AcceptToMemoryPool(txdb, fCheckInputs, pfMissingInputs);
|
||||
}
|
||||
|
||||
protected:
|
||||
bool AddToMemoryPool();
|
||||
bool AddToMemoryPoolUnchecked();
|
||||
public:
|
||||
bool RemoveFromMemoryPool();
|
||||
};
|
||||
@@ -668,9 +709,7 @@ public:
|
||||
int nIndex;
|
||||
|
||||
// memory only
|
||||
mutable bool fMerkleVerified;
|
||||
mutable bool fGetCreditCached;
|
||||
mutable int64 nGetCreditCached;
|
||||
mutable char fMerkleVerified;
|
||||
|
||||
|
||||
CMerkleTx()
|
||||
@@ -688,8 +727,6 @@ public:
|
||||
hashBlock = 0;
|
||||
nIndex = -1;
|
||||
fMerkleVerified = false;
|
||||
fGetCreditCached = false;
|
||||
nGetCreditCached = 0;
|
||||
}
|
||||
|
||||
IMPLEMENT_SERIALIZE
|
||||
@@ -701,28 +738,14 @@ public:
|
||||
READWRITE(nIndex);
|
||||
)
|
||||
|
||||
int64 GetCredit(bool fUseCache=false) const
|
||||
{
|
||||
// Must wait until coinbase is safely deep enough in the chain before valuing it
|
||||
if (IsCoinBase() && GetBlocksToMaturity() > 0)
|
||||
return 0;
|
||||
|
||||
// GetBalance can assume transactions in mapWallet won't change
|
||||
if (fUseCache && fGetCreditCached)
|
||||
return nGetCreditCached;
|
||||
nGetCreditCached = CTransaction::GetCredit();
|
||||
fGetCreditCached = true;
|
||||
return nGetCreditCached;
|
||||
}
|
||||
|
||||
|
||||
int SetMerkleBranch(const CBlock* pblock=NULL);
|
||||
int GetDepthInMainChain(int& nHeightRet) const;
|
||||
int GetDepthInMainChain() const { int nHeight; return GetDepthInMainChain(nHeight); }
|
||||
bool IsInMainChain() const { return GetDepthInMainChain() > 0; }
|
||||
int GetBlocksToMaturity() const;
|
||||
bool AcceptTransaction(CTxDB& txdb, bool fCheckInputs=true);
|
||||
bool AcceptTransaction() { CTxDB txdb("r"); return AcceptTransaction(txdb); }
|
||||
bool AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs=true);
|
||||
bool AcceptToMemoryPool() { CTxDB txdb("r"); return AcceptToMemoryPool(txdb); }
|
||||
};
|
||||
|
||||
|
||||
@@ -743,11 +766,20 @@ public:
|
||||
unsigned int nTimeReceived; // time received by this node
|
||||
char fFromMe;
|
||||
char fSpent;
|
||||
//// probably need to sign the order info so know it came from payer
|
||||
string strFromAccount;
|
||||
|
||||
// memory only
|
||||
mutable char fDebitCached;
|
||||
mutable char fCreditCached;
|
||||
mutable char fChangeCached;
|
||||
mutable int64 nDebitCached;
|
||||
mutable int64 nCreditCached;
|
||||
mutable int64 nChangeCached;
|
||||
|
||||
// memory only UI hints
|
||||
mutable unsigned int nTimeDisplayed;
|
||||
mutable int nLinesDisplayed;
|
||||
mutable char fConfirmedDisplayed;
|
||||
|
||||
|
||||
CWalletTx()
|
||||
@@ -767,20 +799,39 @@ public:
|
||||
|
||||
void Init()
|
||||
{
|
||||
vtxPrev.clear();
|
||||
mapValue.clear();
|
||||
vOrderForm.clear();
|
||||
fTimeReceivedIsTxTime = false;
|
||||
nTimeReceived = 0;
|
||||
fFromMe = false;
|
||||
fSpent = false;
|
||||
strFromAccount.clear();
|
||||
fDebitCached = false;
|
||||
fCreditCached = false;
|
||||
fChangeCached = false;
|
||||
nDebitCached = 0;
|
||||
nCreditCached = 0;
|
||||
nChangeCached = 0;
|
||||
nTimeDisplayed = 0;
|
||||
nLinesDisplayed = 0;
|
||||
fConfirmedDisplayed = false;
|
||||
}
|
||||
|
||||
IMPLEMENT_SERIALIZE
|
||||
(
|
||||
CWalletTx* pthis = const_cast<CWalletTx*>(this);
|
||||
if (fRead)
|
||||
pthis->Init();
|
||||
nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion, ser_action);
|
||||
nVersion = this->nVersion;
|
||||
READWRITE(vtxPrev);
|
||||
|
||||
pthis->mapValue["fromaccount"] = pthis->strFromAccount;
|
||||
READWRITE(mapValue);
|
||||
pthis->strFromAccount = pthis->mapValue["fromaccount"];
|
||||
pthis->mapValue.erase("fromaccount");
|
||||
pthis->mapValue.erase("version");
|
||||
|
||||
READWRITE(vOrderForm);
|
||||
READWRITE(fTimeReceivedIsTxTime);
|
||||
READWRITE(nTimeReceived);
|
||||
@@ -788,6 +839,117 @@ public:
|
||||
READWRITE(fSpent);
|
||||
)
|
||||
|
||||
int64 GetDebit() const
|
||||
{
|
||||
if (vin.empty())
|
||||
return 0;
|
||||
if (fDebitCached)
|
||||
return nDebitCached;
|
||||
nDebitCached = CTransaction::GetDebit();
|
||||
fDebitCached = true;
|
||||
return nDebitCached;
|
||||
}
|
||||
|
||||
int64 GetCredit(bool fUseCache=true) const
|
||||
{
|
||||
// Must wait until coinbase is safely deep enough in the chain before valuing it
|
||||
if (IsCoinBase() && GetBlocksToMaturity() > 0)
|
||||
return 0;
|
||||
|
||||
// GetBalance can assume transactions in mapWallet won't change
|
||||
if (fUseCache && fCreditCached)
|
||||
return nCreditCached;
|
||||
nCreditCached = CTransaction::GetCredit();
|
||||
fCreditCached = true;
|
||||
return nCreditCached;
|
||||
}
|
||||
|
||||
int64 GetChange() const
|
||||
{
|
||||
if (fChangeCached)
|
||||
return nChangeCached;
|
||||
nChangeCached = CTransaction::GetChange();
|
||||
fChangeCached = true;
|
||||
return nChangeCached;
|
||||
}
|
||||
|
||||
void GetAccountAmounts(string strAccount, const set<CScript>& setPubKey,
|
||||
int64& nGenerated, int64& nReceived, int64& nSent, int64& nFee) const
|
||||
{
|
||||
nGenerated = nReceived = nSent = nFee = 0;
|
||||
|
||||
// Generated blocks count to account ""
|
||||
if (IsCoinBase())
|
||||
{
|
||||
if (strAccount == "" && GetBlocksToMaturity() == 0)
|
||||
nGenerated = GetCredit();
|
||||
return;
|
||||
}
|
||||
|
||||
// Received
|
||||
foreach(const CTxOut& txout, vout)
|
||||
if (setPubKey.count(txout.scriptPubKey))
|
||||
nReceived += txout.nValue;
|
||||
|
||||
// Sent
|
||||
if (strFromAccount == strAccount)
|
||||
{
|
||||
int64 nDebit = GetDebit();
|
||||
if (nDebit > 0)
|
||||
{
|
||||
int64 nValueOut = GetValueOut();
|
||||
nFee = nDebit - nValueOut;
|
||||
nSent = nValueOut - GetChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool IsFromMe() const
|
||||
{
|
||||
return (GetDebit() > 0);
|
||||
}
|
||||
|
||||
bool IsConfirmed() const
|
||||
{
|
||||
// Quick answer in most cases
|
||||
if (!IsFinal())
|
||||
return false;
|
||||
if (GetDepthInMainChain() >= 1)
|
||||
return true;
|
||||
if (!IsFromMe()) // using wtx's cached debit
|
||||
return false;
|
||||
|
||||
// If no confirmations but it's from us, we can still
|
||||
// consider it confirmed if all dependencies are confirmed
|
||||
map<uint256, const CMerkleTx*> mapPrev;
|
||||
vector<const CMerkleTx*> vWorkQueue;
|
||||
vWorkQueue.reserve(vtxPrev.size()+1);
|
||||
vWorkQueue.push_back(this);
|
||||
for (int i = 0; i < vWorkQueue.size(); i++)
|
||||
{
|
||||
const CMerkleTx* ptx = vWorkQueue[i];
|
||||
|
||||
if (!ptx->IsFinal())
|
||||
return false;
|
||||
if (ptx->GetDepthInMainChain() >= 1)
|
||||
return true;
|
||||
if (!ptx->IsFromMe())
|
||||
return false;
|
||||
|
||||
if (mapPrev.empty())
|
||||
foreach(const CMerkleTx& tx, vtxPrev)
|
||||
mapPrev[tx.GetHash()] = &tx;
|
||||
|
||||
foreach(const CTxIn& txin, ptx->vin)
|
||||
{
|
||||
if (!mapPrev.count(txin.prevout.hash))
|
||||
return false;
|
||||
vWorkQueue.push_back(mapPrev[txin.prevout.hash]);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteToDisk()
|
||||
{
|
||||
return CWalletDB().WriteTx(GetHash(), *this);
|
||||
@@ -852,12 +1014,8 @@ public:
|
||||
|
||||
friend bool operator==(const CTxIndex& a, const CTxIndex& b)
|
||||
{
|
||||
if (a.pos != b.pos || a.vSpent.size() != b.vSpent.size())
|
||||
return false;
|
||||
for (int i = 0; i < a.vSpent.size(); i++)
|
||||
if (a.vSpent[i] != b.vSpent[i])
|
||||
return false;
|
||||
return true;
|
||||
return (a.pos == b.pos &&
|
||||
a.vSpent == b.vSpent);
|
||||
}
|
||||
|
||||
friend bool operator!=(const CTxIndex& a, const CTxIndex& b)
|
||||
@@ -948,6 +1106,14 @@ public:
|
||||
return (int64)nTime;
|
||||
}
|
||||
|
||||
int GetSigOpCount() const
|
||||
{
|
||||
int n = 0;
|
||||
foreach(const CTransaction& tx, vtx)
|
||||
n += tx.GetSigOpCount();
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
uint256 BuildMerkleTree() const
|
||||
{
|
||||
@@ -1000,14 +1166,12 @@ public:
|
||||
}
|
||||
|
||||
|
||||
bool WriteToDisk(bool fWriteTransactions, unsigned int& nFileRet, unsigned int& nBlockPosRet)
|
||||
bool WriteToDisk(unsigned int& nFileRet, unsigned int& nBlockPosRet)
|
||||
{
|
||||
// Open history file to append
|
||||
CAutoFile fileout = AppendBlockFile(nFileRet);
|
||||
if (!fileout)
|
||||
return error("CBlock::WriteToDisk() : AppendBlockFile failed");
|
||||
if (!fWriteTransactions)
|
||||
fileout.nType |= SER_BLOCKHEADERONLY;
|
||||
|
||||
// Write index header
|
||||
unsigned int nSize = fileout.GetSerializeSize(*this);
|
||||
@@ -1062,7 +1226,7 @@ public:
|
||||
GetHash().ToString().substr(0,20).c_str(),
|
||||
nVersion,
|
||||
hashPrevBlock.ToString().substr(0,20).c_str(),
|
||||
hashMerkleRoot.ToString().substr(0,6).c_str(),
|
||||
hashMerkleRoot.ToString().substr(0,10).c_str(),
|
||||
nTime, nBits, nNonce,
|
||||
vtx.size());
|
||||
for (int i = 0; i < vtx.size(); i++)
|
||||
@@ -1072,12 +1236,11 @@ public:
|
||||
}
|
||||
printf(" vMerkleTree: ");
|
||||
for (int i = 0; i < vMerkleTree.size(); i++)
|
||||
printf("%s ", vMerkleTree[i].ToString().substr(0,6).c_str());
|
||||
printf("%s ", vMerkleTree[i].ToString().substr(0,10).c_str());
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
int64 GetBlockValue(int nHeight, int64 nFees) const;
|
||||
bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex);
|
||||
bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex);
|
||||
bool ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions=true);
|
||||
@@ -1153,6 +1316,19 @@ public:
|
||||
nNonce = block.nNonce;
|
||||
}
|
||||
|
||||
CBlock GetBlockHeader() const
|
||||
{
|
||||
CBlock block;
|
||||
block.nVersion = nVersion;
|
||||
if (pprev)
|
||||
block.hashPrevBlock = pprev->GetBlockHash();
|
||||
block.hashMerkleRoot = hashMerkleRoot;
|
||||
block.nTime = nTime;
|
||||
block.nBits = nBits;
|
||||
block.nNonce = nNonce;
|
||||
return block;
|
||||
}
|
||||
|
||||
uint256 GetBlockHash() const
|
||||
{
|
||||
return *phashBlock;
|
||||
@@ -1165,9 +1341,11 @@ public:
|
||||
|
||||
CBigNum GetBlockWork() const
|
||||
{
|
||||
if (CBigNum().SetCompact(nBits) <= 0)
|
||||
CBigNum bnTarget;
|
||||
bnTarget.SetCompact(nBits);
|
||||
if (bnTarget <= 0)
|
||||
return 0;
|
||||
return (CBigNum(1)<<256) / (CBigNum().SetCompact(nBits)+1);
|
||||
return (CBigNum(1)<<256) / (bnTarget+1);
|
||||
}
|
||||
|
||||
bool IsInMainChain() const
|
||||
@@ -1229,7 +1407,7 @@ public:
|
||||
{
|
||||
return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)",
|
||||
pprev, pnext, nFile, nBlockPos, nHeight,
|
||||
hashMerkleRoot.ToString().substr(0,6).c_str(),
|
||||
hashMerkleRoot.ToString().substr(0,10).c_str(),
|
||||
GetBlockHash().ToString().substr(0,20).c_str());
|
||||
}
|
||||
|
||||
@@ -1352,6 +1530,16 @@ public:
|
||||
READWRITE(vHave);
|
||||
)
|
||||
|
||||
void SetNull()
|
||||
{
|
||||
vHave.clear();
|
||||
}
|
||||
|
||||
bool IsNull()
|
||||
{
|
||||
return vHave.empty();
|
||||
}
|
||||
|
||||
void Set(const CBlockIndex* pindex)
|
||||
{
|
||||
vHave.clear();
|
||||
@@ -1449,10 +1637,10 @@ public:
|
||||
//// todo: add something to note what created it (user, getnewaddress, change)
|
||||
//// maybe should have a map<string, string> property map
|
||||
|
||||
CWalletKey(int64 nTimeExpiresIn=0)
|
||||
CWalletKey(int64 nExpires=0)
|
||||
{
|
||||
nTimeCreated = (nTimeExpiresIn ? GetTime() : 0);
|
||||
nTimeExpires = nTimeExpiresIn;
|
||||
nTimeCreated = (nExpires ? GetTime() : 0);
|
||||
nTimeExpires = nExpires;
|
||||
}
|
||||
|
||||
IMPLEMENT_SERIALIZE
|
||||
@@ -1471,6 +1659,79 @@ public:
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Account information.
|
||||
// Stored in wallet with key "acc"+string account name
|
||||
//
|
||||
class CAccount
|
||||
{
|
||||
public:
|
||||
vector<unsigned char> vchPubKey;
|
||||
|
||||
CAccount()
|
||||
{
|
||||
SetNull();
|
||||
}
|
||||
|
||||
void SetNull()
|
||||
{
|
||||
vchPubKey.clear();
|
||||
}
|
||||
|
||||
IMPLEMENT_SERIALIZE
|
||||
(
|
||||
if (!(nType & SER_GETHASH))
|
||||
READWRITE(nVersion);
|
||||
READWRITE(vchPubKey);
|
||||
)
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Internal transfers.
|
||||
// Database key is acentry<account><counter>
|
||||
//
|
||||
class CAccountingEntry
|
||||
{
|
||||
public:
|
||||
int64 nCreditDebit;
|
||||
int64 nTime;
|
||||
string strOtherAccount;
|
||||
string strComment;
|
||||
|
||||
CAccountingEntry()
|
||||
{
|
||||
SetNull();
|
||||
}
|
||||
|
||||
void SetNull()
|
||||
{
|
||||
nCreditDebit = 0;
|
||||
nTime = 0;
|
||||
strOtherAccount.clear();
|
||||
strComment.clear();
|
||||
}
|
||||
|
||||
IMPLEMENT_SERIALIZE
|
||||
(
|
||||
if (!(nType & SER_GETHASH))
|
||||
READWRITE(nVersion);
|
||||
READWRITE(nCreditDebit);
|
||||
READWRITE(nTime);
|
||||
READWRITE(strOtherAccount);
|
||||
READWRITE(strComment);
|
||||
)
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Alert messages are broadcast as a vector of signed data. Unserializing may
|
||||
// not read the entire buffer if the alert is for a newer version, but older
|
||||
@@ -1619,7 +1880,7 @@ public:
|
||||
bool Cancels(const CAlert& alert) const
|
||||
{
|
||||
if (!IsInEffect())
|
||||
false;
|
||||
return false; // this was a no-op before 31403
|
||||
return (alert.nID <= nCancel || setCancel.count(alert.nID));
|
||||
}
|
||||
|
||||
|
||||
@@ -22,9 +22,10 @@ LIBS= -dead_strip \
|
||||
$(DEPSDIR)/lib/libboost_filesystem.a \
|
||||
$(DEPSDIR)/lib/libboost_program_options.a \
|
||||
$(DEPSDIR)/lib/libboost_thread.a \
|
||||
$(DEPSDIR)/lib/libssl.a \
|
||||
$(DEPSDIR)/lib/libcrypto.a
|
||||
|
||||
DEFS=$(shell $(DEPSDIR)/bin/wx-config --cxxflags) -D__WXMAC_OSX__ -DNOPCH -DMSG_NOSIGNAL=0
|
||||
DEFS=$(shell $(DEPSDIR)/bin/wx-config --cxxflags) -D__WXMAC_OSX__ -DNOPCH -DMSG_NOSIGNAL=0 -DUSE_SSL
|
||||
|
||||
DEBUGFLAGS=-g -DwxDEBUG_LEVEL=0
|
||||
# ppc doesn't work because we don't support big-endian
|
||||
|
||||
@@ -7,11 +7,13 @@ INCLUDEPATHS= \
|
||||
-I"/usr/local/include/wx-2.9" \
|
||||
-I"/usr/local/lib/wx/include/gtk2-unicode-debug-static-2.9"
|
||||
|
||||
# for wxWidgets 2.9.1, add -l Xxf86vm
|
||||
WXLIBS= \
|
||||
-Wl,-Bstatic \
|
||||
-l wx_gtk2ud-2.9 \
|
||||
-Wl,-Bdynamic \
|
||||
-l gtk-x11-2.0 -l SM
|
||||
-l gtk-x11-2.0 \
|
||||
-l SM
|
||||
|
||||
# for boost 1.37, add -mt to the boost libraries
|
||||
LIBS= \
|
||||
@@ -21,11 +23,14 @@ LIBS= \
|
||||
-l boost_program_options \
|
||||
-l boost_thread \
|
||||
-l db_cxx \
|
||||
-l ssl \
|
||||
-l crypto \
|
||||
-Wl,-Bdynamic \
|
||||
-l gthread-2.0
|
||||
-l gthread-2.0 \
|
||||
-l z \
|
||||
-l dl
|
||||
|
||||
DEFS=-D__WXGTK__ -DNOPCH -DFOURWAYSSE2
|
||||
DEFS=-D__WXGTK__ -DNOPCH -DFOURWAYSSE2 -DUSE_SSL
|
||||
DEBUGFLAGS=-g -D__WXDEBUG__
|
||||
CFLAGS=-O2 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
|
||||
HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \
|
||||
|
||||
142
net.cpp
142
net.cpp
@@ -20,12 +20,11 @@ bool OpenNetworkConnection(const CAddress& addrConnect);
|
||||
//
|
||||
bool fClient = false;
|
||||
uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
|
||||
CAddress addrLocalHost(0, DEFAULT_PORT, nLocalServices);
|
||||
CAddress addrLocalHost(0, 0, nLocalServices);
|
||||
CNode* pnodeLocalHost = NULL;
|
||||
uint64 nLocalHostNonce = 0;
|
||||
array<int, 10> vnThreadsRunning;
|
||||
SOCKET hListenSocket = INVALID_SOCKET;
|
||||
int64 nThreadSocketHandlerHeartbeat = INT64_MAX;
|
||||
|
||||
vector<CNode*> vNodes;
|
||||
CCriticalSection cs_vNodes;
|
||||
@@ -129,7 +128,7 @@ bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const cha
|
||||
string strLine;
|
||||
while (RecvLine(hSocket, strLine))
|
||||
{
|
||||
if (strLine.empty())
|
||||
if (strLine.empty()) // HTTP response is separated from headers by blank line
|
||||
{
|
||||
loop
|
||||
{
|
||||
@@ -138,6 +137,8 @@ bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const cha
|
||||
closesocket(hSocket);
|
||||
return false;
|
||||
}
|
||||
if (pszKeyword == NULL)
|
||||
break;
|
||||
if (strLine.find(pszKeyword) != -1)
|
||||
{
|
||||
strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
|
||||
@@ -145,7 +146,7 @@ bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const cha
|
||||
}
|
||||
}
|
||||
closesocket(hSocket);
|
||||
if (strLine.find("<"))
|
||||
if (strLine.find("<") != -1)
|
||||
strLine = strLine.substr(0, strLine.find("<"));
|
||||
strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
|
||||
while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
|
||||
@@ -177,26 +178,7 @@ bool GetMyExternalIP(unsigned int& ipRet)
|
||||
{
|
||||
if (nHost == 1)
|
||||
{
|
||||
addrConnect = CAddress("70.86.96.218:80"); // www.ipaddressworld.com
|
||||
|
||||
if (nLookup == 1)
|
||||
{
|
||||
struct hostent* phostent = gethostbyname("www.ipaddressworld.com");
|
||||
if (phostent && phostent->h_addr_list && phostent->h_addr_list[0])
|
||||
addrConnect = CAddress(*(u_long*)phostent->h_addr_list[0], htons(80));
|
||||
}
|
||||
|
||||
pszGet = "GET /ip.php HTTP/1.1\r\n"
|
||||
"Host: www.ipaddressworld.com\r\n"
|
||||
"User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
|
||||
"Connection: close\r\n"
|
||||
"\r\n";
|
||||
|
||||
pszKeyword = "IP:";
|
||||
}
|
||||
else if (nHost == 2)
|
||||
{
|
||||
addrConnect = CAddress("208.78.68.70:80"); // checkip.dyndns.org
|
||||
addrConnect = CAddress("91.198.22.70:80"); // checkip.dyndns.org
|
||||
|
||||
if (nLookup == 1)
|
||||
{
|
||||
@@ -213,6 +195,25 @@ bool GetMyExternalIP(unsigned int& ipRet)
|
||||
|
||||
pszKeyword = "Address:";
|
||||
}
|
||||
else if (nHost == 2)
|
||||
{
|
||||
addrConnect = CAddress("74.208.43.192:80"); // www.showmyip.com
|
||||
|
||||
if (nLookup == 1)
|
||||
{
|
||||
struct hostent* phostent = gethostbyname("www.showmyip.com");
|
||||
if (phostent && phostent->h_addr_list && phostent->h_addr_list[0])
|
||||
addrConnect = CAddress(*(u_long*)phostent->h_addr_list[0], htons(80));
|
||||
}
|
||||
|
||||
pszGet = "GET /simple/ HTTP/1.1\r\n"
|
||||
"Host: www.showmyip.com\r\n"
|
||||
"User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
|
||||
"Connection: close\r\n"
|
||||
"\r\n";
|
||||
|
||||
pszKeyword = NULL; // Returns just IP address
|
||||
}
|
||||
|
||||
if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
|
||||
return true;
|
||||
@@ -225,12 +226,13 @@ bool GetMyExternalIP(unsigned int& ipRet)
|
||||
|
||||
|
||||
|
||||
bool AddAddress(CAddress addr)
|
||||
bool AddAddress(CAddress addr, int64 nTimePenalty)
|
||||
{
|
||||
if (!addr.IsRoutable())
|
||||
return false;
|
||||
if (addr.ip == addrLocalHost.ip)
|
||||
return false;
|
||||
addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
|
||||
CRITICAL_BLOCK(cs_mapAddresses)
|
||||
{
|
||||
map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
|
||||
@@ -789,7 +791,6 @@ void ThreadSocketHandler2(void* parg)
|
||||
pnode->Release();
|
||||
}
|
||||
|
||||
nThreadSocketHandlerHeartbeat = GetTime();
|
||||
Sleep(10);
|
||||
}
|
||||
}
|
||||
@@ -939,7 +940,7 @@ void ThreadOpenConnections2(void* parg)
|
||||
// Add seed nodes if IRC isn't working
|
||||
static bool fSeedUsed;
|
||||
bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
|
||||
if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR))
|
||||
if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
|
||||
{
|
||||
for (int i = 0; i < ARRAYLEN(pnSeed); i++)
|
||||
{
|
||||
@@ -1008,7 +1009,7 @@ void ThreadOpenConnections2(void* parg)
|
||||
|
||||
// Randomize the order in a deterministic way, putting the standard port first
|
||||
int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
|
||||
if (addr.port != DEFAULT_PORT)
|
||||
if (addr.port != GetDefaultPort())
|
||||
nRandomizer += 2 * 60 * 60;
|
||||
|
||||
// Last seen Base retry frequency
|
||||
@@ -1075,25 +1076,6 @@ bool OpenNetworkConnection(const CAddress& addrConnect)
|
||||
return false;
|
||||
pnode->fNetworkNode = true;
|
||||
|
||||
if (addrLocalHost.IsRoutable() && !fUseProxy)
|
||||
{
|
||||
// Advertise our address
|
||||
vector<CAddress> vAddr;
|
||||
vAddr.push_back(addrLocalHost);
|
||||
pnode->PushMessage("addr", vAddr);
|
||||
}
|
||||
|
||||
// Get as many addresses as we can
|
||||
pnode->PushMessage("getaddr");
|
||||
pnode->fGetAddr = true; // don't relay the results of the getaddr
|
||||
|
||||
////// should the one on the receiving end do this too?
|
||||
// Subscribe our local subscription list
|
||||
const unsigned int nHops = 0;
|
||||
for (unsigned int nChannel = 0; nChannel < pnodeLocalHost->vfSubscribe.size(); nChannel++)
|
||||
if (pnodeLocalHost->vfSubscribe[nChannel])
|
||||
pnode->PushMessage("subscribe", nChannel, nHops);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1162,9 +1144,13 @@ void ThreadMessageHandler2(void* parg)
|
||||
pnode->Release();
|
||||
}
|
||||
|
||||
// Wait and allow messages to bunch up
|
||||
// Wait and allow messages to bunch up.
|
||||
// Reduce vnThreadsRunning so StopNode has permission to exit while
|
||||
// we're sleeping, but we must always check fShutdown after doing this.
|
||||
vnThreadsRunning[2]--;
|
||||
Sleep(100);
|
||||
if (fRequestShutdown)
|
||||
Shutdown(NULL);
|
||||
vnThreadsRunning[2]++;
|
||||
if (fShutdown)
|
||||
return;
|
||||
@@ -1183,6 +1169,7 @@ bool BindListenPort(string& strError)
|
||||
{
|
||||
strError = "";
|
||||
int nOne = 1;
|
||||
addrLocalHost.port = GetDefaultPort();
|
||||
|
||||
#ifdef __WXMSW__
|
||||
// Initialize Windows Sockets
|
||||
@@ -1234,12 +1221,12 @@ bool BindListenPort(string& strError)
|
||||
memset(&sockaddr, 0, sizeof(sockaddr));
|
||||
sockaddr.sin_family = AF_INET;
|
||||
sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
|
||||
sockaddr.sin_port = DEFAULT_PORT;
|
||||
sockaddr.sin_port = GetDefaultPort();
|
||||
if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
|
||||
{
|
||||
int nErr = WSAGetLastError();
|
||||
if (nErr == WSAEADDRINUSE)
|
||||
strError = strprintf("Unable to bind to port %d on this computer. Bitcoin is probably already running.", ntohs(sockaddr.sin_port));
|
||||
strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
|
||||
else
|
||||
strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
|
||||
printf("%s\n", strError.c_str());
|
||||
@@ -1276,7 +1263,7 @@ void StartNode(void* parg)
|
||||
printf("host ip %d: %s\n", i, CAddress(*(unsigned int*)phostent->h_addr_list[i]).ToStringIP().c_str());
|
||||
for (int i = 0; phostent->h_addr_list[i] != NULL; i++)
|
||||
{
|
||||
CAddress addr(*(unsigned int*)phostent->h_addr_list[i], DEFAULT_PORT, nLocalServices);
|
||||
CAddress addr(*(unsigned int*)phostent->h_addr_list[i], GetDefaultPort(), nLocalServices);
|
||||
if (addr.IsValid() && addr.GetByte(3) != 127)
|
||||
{
|
||||
addrLocalHost = addr;
|
||||
@@ -1304,7 +1291,7 @@ void StartNode(void* parg)
|
||||
printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
|
||||
|
||||
// Take the first IP that isn't loopback 127.x.x.x
|
||||
CAddress addr(*(unsigned int*)&s4->sin_addr, DEFAULT_PORT, nLocalServices);
|
||||
CAddress addr(*(unsigned int*)&s4->sin_addr, GetDefaultPort(), nLocalServices);
|
||||
if (addr.IsValid() && addr.GetByte(3) != 127)
|
||||
{
|
||||
addrLocalHost = addr;
|
||||
@@ -1364,57 +1351,6 @@ void StartNode(void* parg)
|
||||
|
||||
// Generate coins in the background
|
||||
GenerateBitcoins(fGenerateBitcoins);
|
||||
|
||||
//
|
||||
// Thread monitoring
|
||||
// Not really needed anymore, the cause of the hanging was fixed
|
||||
//
|
||||
loop
|
||||
{
|
||||
Sleep(1000);
|
||||
if (fShutdown)
|
||||
return;
|
||||
if (GetTime() - nThreadSocketHandlerHeartbeat > 15 * 60)
|
||||
{
|
||||
// First see if closing sockets will free it
|
||||
printf("*** ThreadSocketHandler is stopped ***\n");
|
||||
CRITICAL_BLOCK(cs_vNodes)
|
||||
{
|
||||
foreach(CNode* pnode, vNodes)
|
||||
{
|
||||
bool fGot = false;
|
||||
TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
|
||||
TRY_CRITICAL_BLOCK(pnode->cs_vSend)
|
||||
fGot = true;
|
||||
if (!fGot)
|
||||
{
|
||||
printf("*** closing socket\n");
|
||||
pnode->CloseSocketDisconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
Sleep(10000);
|
||||
if (fShutdown)
|
||||
return;
|
||||
if (GetTime() - nThreadSocketHandlerHeartbeat < 60)
|
||||
continue;
|
||||
|
||||
// Hopefully it never comes to this.
|
||||
// We know it'll always be hung in the recv or send call.
|
||||
// cs_vRecv or cs_vSend may be left permanently unreleased,
|
||||
// but we always only use TRY_CRITICAL_SECTION on them.
|
||||
printf("*** Restarting ThreadSocketHandler ***\n");
|
||||
TerminateThread(hThreadSocketHandler, 0);
|
||||
#ifdef __WXMSW__
|
||||
CloseHandle(hThreadSocketHandler);
|
||||
#endif
|
||||
vnThreadsRunning[0] = 0;
|
||||
|
||||
// Restart
|
||||
hThreadSocketHandler = CreateThread(ThreadSocketHandler, NULL, true);
|
||||
nThreadSocketHandlerHeartbeat = GetTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool StopNode()
|
||||
|
||||
40
net.h
40
net.h
@@ -12,7 +12,7 @@ extern int nBestHeight;
|
||||
|
||||
|
||||
|
||||
static const unsigned short DEFAULT_PORT = 0x8d20; // htons(8333)
|
||||
inline unsigned short GetDefaultPort() { return fTestNet ? htons(18333) : htons(8333); }
|
||||
static const unsigned int PUBLISH_HOPS = 5;
|
||||
enum
|
||||
{
|
||||
@@ -24,7 +24,7 @@ enum
|
||||
|
||||
bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet);
|
||||
bool GetMyExternalIP(unsigned int& ipRet);
|
||||
bool AddAddress(CAddress addr);
|
||||
bool AddAddress(CAddress addr, int64 nTimePenalty=0);
|
||||
void AddressCurrentlyConnected(const CAddress& addr);
|
||||
CNode* FindNode(unsigned int ip);
|
||||
CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0);
|
||||
@@ -48,10 +48,7 @@ bool StopNode();
|
||||
// (4) size
|
||||
// (4) checksum
|
||||
|
||||
// The message start string is designed to be unlikely to occur in normal data.
|
||||
// The characters are rarely used upper ascii, not valid as UTF-8, and produce
|
||||
// a large 4-byte int at any alignment.
|
||||
static const char pchMessageStart[4] = { 0xf9, 0xbe, 0xb4, 0xd9 };
|
||||
extern char pchMessageStart[4];
|
||||
|
||||
class CMessageHeader
|
||||
{
|
||||
@@ -117,9 +114,9 @@ public:
|
||||
}
|
||||
|
||||
// Message size
|
||||
if (nMessageSize > 0x10000000)
|
||||
if (nMessageSize > MAX_SIZE)
|
||||
{
|
||||
printf("CMessageHeader::IsValid() : nMessageSize too large %u\n", nMessageSize);
|
||||
printf("CMessageHeader::IsValid() : (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand().c_str(), nMessageSize);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -142,7 +139,7 @@ public:
|
||||
unsigned int ip;
|
||||
unsigned short port;
|
||||
|
||||
// disk only
|
||||
// disk and network only
|
||||
unsigned int nTime;
|
||||
|
||||
// memory only
|
||||
@@ -153,11 +150,11 @@ public:
|
||||
Init();
|
||||
}
|
||||
|
||||
CAddress(unsigned int ipIn, unsigned short portIn=DEFAULT_PORT, uint64 nServicesIn=NODE_NETWORK)
|
||||
CAddress(unsigned int ipIn, unsigned short portIn=0, uint64 nServicesIn=NODE_NETWORK)
|
||||
{
|
||||
Init();
|
||||
ip = ipIn;
|
||||
port = portIn;
|
||||
port = (portIn == 0 ? GetDefaultPort() : portIn);
|
||||
nServices = nServicesIn;
|
||||
}
|
||||
|
||||
@@ -188,15 +185,15 @@ public:
|
||||
nServices = NODE_NETWORK;
|
||||
memcpy(pchReserved, pchIPv4, sizeof(pchReserved));
|
||||
ip = INADDR_NONE;
|
||||
port = DEFAULT_PORT;
|
||||
nTime = GetAdjustedTime();
|
||||
port = GetDefaultPort();
|
||||
nTime = 100000000;
|
||||
nLastTry = 0;
|
||||
}
|
||||
|
||||
bool SetAddress(const char* pszIn)
|
||||
{
|
||||
ip = INADDR_NONE;
|
||||
port = DEFAULT_PORT;
|
||||
port = GetDefaultPort();
|
||||
char psz[100];
|
||||
strlcpy(psz, pszIn, sizeof(psz));
|
||||
unsigned int a=0, b=0, c=0, d=0, e=0;
|
||||
@@ -221,11 +218,12 @@ public:
|
||||
|
||||
IMPLEMENT_SERIALIZE
|
||||
(
|
||||
if (fRead)
|
||||
const_cast<CAddress*>(this)->Init();
|
||||
if (nType & SER_DISK)
|
||||
{
|
||||
READWRITE(nVersion);
|
||||
if ((nType & SER_DISK) || (nVersion >= 31402 && !(nType & SER_GETHASH)))
|
||||
READWRITE(nTime);
|
||||
}
|
||||
READWRITE(nServices);
|
||||
READWRITE(FLATDATA(pchReserved)); // for IPv6
|
||||
READWRITE(ip);
|
||||
@@ -418,7 +416,7 @@ public:
|
||||
const char* GetCommand() const
|
||||
{
|
||||
if (!IsKnownType())
|
||||
throw std::out_of_range(strprintf("CInv::GetCommand() : type=% unknown type", type));
|
||||
throw std::out_of_range(strprintf("CInv::GetCommand() : type=%d unknown type", type));
|
||||
return ppszTypeName[type];
|
||||
}
|
||||
|
||||
@@ -466,7 +464,6 @@ extern CNode* pnodeLocalHost;
|
||||
extern uint64 nLocalHostNonce;
|
||||
extern array<int, 10> vnThreadsRunning;
|
||||
extern SOCKET hListenSocket;
|
||||
extern int64 nThreadSocketHandlerHeartbeat;
|
||||
|
||||
extern vector<CNode*> vNodes;
|
||||
extern CCriticalSection cs_vNodes;
|
||||
@@ -736,13 +733,6 @@ public:
|
||||
AbortMessage();
|
||||
}
|
||||
|
||||
const char* GetMessageCommand() const
|
||||
{
|
||||
if (nHeaderStart == -1)
|
||||
return "";
|
||||
return &vSend[nHeaderStart] + offsetof(CMessageHeader, pchCommand);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
124
script.cpp
124
script.cpp
@@ -59,6 +59,13 @@ void MakeSameSize(valtype& vch1, valtype& vch2)
|
||||
//
|
||||
#define stacktop(i) (stack.at(stack.size()+(i)))
|
||||
#define altstacktop(i) (altstack.at(altstack.size()+(i)))
|
||||
static inline void popstack(vector<valtype>& stack)
|
||||
{
|
||||
if (stack.empty())
|
||||
throw runtime_error("popstack() : stack empty");
|
||||
stack.pop_back();
|
||||
}
|
||||
|
||||
|
||||
bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType)
|
||||
{
|
||||
@@ -66,6 +73,8 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
||||
CScript::const_iterator pc = script.begin();
|
||||
CScript::const_iterator pend = script.end();
|
||||
CScript::const_iterator pbegincodehash = script.begin();
|
||||
opcodetype opcode;
|
||||
valtype vchPushValue;
|
||||
vector<bool> vfExec;
|
||||
vector<valtype> altstack;
|
||||
if (script.size() > 10000)
|
||||
@@ -82,13 +91,11 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
||||
//
|
||||
// Read instruction
|
||||
//
|
||||
opcodetype opcode;
|
||||
valtype vchPushValue;
|
||||
if (!script.GetOp(pc, opcode, vchPushValue))
|
||||
return false;
|
||||
if (vchPushValue.size() > 520)
|
||||
return false;
|
||||
if (opcode > OP_16 && nOpCount++ > 200)
|
||||
if (opcode > OP_16 && ++nOpCount > 201)
|
||||
return false;
|
||||
|
||||
if (opcode == OP_CAT ||
|
||||
@@ -108,7 +115,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
||||
opcode == OP_RSHIFT)
|
||||
return false;
|
||||
|
||||
if (fExec && opcode <= OP_PUSHDATA4)
|
||||
if (fExec && 0 <= opcode && opcode <= OP_PUSHDATA4)
|
||||
stack.push_back(vchPushValue);
|
||||
else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF))
|
||||
switch (opcode)
|
||||
@@ -149,14 +156,6 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
||||
case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10:
|
||||
break;
|
||||
|
||||
case OP_VER:
|
||||
case OP_VERIF:
|
||||
case OP_VERNOTIF:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_IF:
|
||||
case OP_NOTIF:
|
||||
{
|
||||
@@ -170,7 +169,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
||||
fValue = CastToBool(vch);
|
||||
if (opcode == OP_NOTIF)
|
||||
fValue = !fValue;
|
||||
stack.pop_back();
|
||||
popstack(stack);
|
||||
}
|
||||
vfExec.push_back(fValue);
|
||||
}
|
||||
@@ -200,7 +199,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
||||
return false;
|
||||
bool fValue = CastToBool(stacktop(-1));
|
||||
if (fValue)
|
||||
stack.pop_back();
|
||||
popstack(stack);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
@@ -221,7 +220,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
||||
if (stack.size() < 1)
|
||||
return false;
|
||||
altstack.push_back(stacktop(-1));
|
||||
stack.pop_back();
|
||||
popstack(stack);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -230,15 +229,17 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
||||
if (altstack.size() < 1)
|
||||
return false;
|
||||
stack.push_back(altstacktop(-1));
|
||||
altstack.pop_back();
|
||||
popstack(altstack);
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_2DROP:
|
||||
{
|
||||
// (x1 x2 -- )
|
||||
stack.pop_back();
|
||||
stack.pop_back();
|
||||
if (stack.size() < 2)
|
||||
return false;
|
||||
popstack(stack);
|
||||
popstack(stack);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -327,7 +328,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
||||
// (x -- )
|
||||
if (stack.size() < 1)
|
||||
return false;
|
||||
stack.pop_back();
|
||||
popstack(stack);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -368,7 +369,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
||||
if (stack.size() < 2)
|
||||
return false;
|
||||
int n = CastToBigNum(stacktop(-1)).getint();
|
||||
stack.pop_back();
|
||||
popstack(stack);
|
||||
if (n < 0 || n >= stack.size())
|
||||
return false;
|
||||
valtype vch = stacktop(-n-1);
|
||||
@@ -421,7 +422,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
||||
valtype& vch1 = stacktop(-2);
|
||||
valtype& vch2 = stacktop(-1);
|
||||
vch1.insert(vch1.end(), vch2.begin(), vch2.end());
|
||||
stack.pop_back();
|
||||
popstack(stack);
|
||||
if (stacktop(-1).size() > 520)
|
||||
return false;
|
||||
}
|
||||
@@ -443,8 +444,8 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
||||
nEnd = vch.size();
|
||||
vch.erase(vch.begin() + nEnd, vch.end());
|
||||
vch.erase(vch.begin(), vch.begin() + nBegin);
|
||||
stack.pop_back();
|
||||
stack.pop_back();
|
||||
popstack(stack);
|
||||
popstack(stack);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -464,7 +465,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
||||
vch.erase(vch.begin() + nSize, vch.end());
|
||||
else
|
||||
vch.erase(vch.begin(), vch.end() - nSize);
|
||||
stack.pop_back();
|
||||
popstack(stack);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -518,7 +519,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
||||
for (int i = 0; i < vch1.size(); i++)
|
||||
vch1[i] ^= vch2[i];
|
||||
}
|
||||
stack.pop_back();
|
||||
popstack(stack);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -537,13 +538,13 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
||||
// zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001)
|
||||
//if (opcode == OP_NOTEQUAL)
|
||||
// fEqual = !fEqual;
|
||||
stack.pop_back();
|
||||
stack.pop_back();
|
||||
popstack(stack);
|
||||
popstack(stack);
|
||||
stack.push_back(fEqual ? vchTrue : vchFalse);
|
||||
if (opcode == OP_EQUALVERIFY)
|
||||
{
|
||||
if (fEqual)
|
||||
stack.pop_back();
|
||||
popstack(stack);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
@@ -578,7 +579,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
||||
case OP_NOT: bn = (bn == bnZero); break;
|
||||
case OP_0NOTEQUAL: bn = (bn != bnZero); break;
|
||||
}
|
||||
stack.pop_back();
|
||||
popstack(stack);
|
||||
stack.push_back(bn.getvch());
|
||||
}
|
||||
break;
|
||||
@@ -657,14 +658,14 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
||||
case OP_MIN: bn = (bn1 < bn2 ? bn1 : bn2); break;
|
||||
case OP_MAX: bn = (bn1 > bn2 ? bn1 : bn2); break;
|
||||
}
|
||||
stack.pop_back();
|
||||
stack.pop_back();
|
||||
popstack(stack);
|
||||
popstack(stack);
|
||||
stack.push_back(bn.getvch());
|
||||
|
||||
if (opcode == OP_NUMEQUALVERIFY)
|
||||
{
|
||||
if (CastToBool(stacktop(-1)))
|
||||
stack.pop_back();
|
||||
popstack(stack);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
@@ -680,9 +681,9 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
||||
CBigNum bn2 = CastToBigNum(stacktop(-2));
|
||||
CBigNum bn3 = CastToBigNum(stacktop(-1));
|
||||
bool fValue = (bn2 <= bn1 && bn1 < bn3);
|
||||
stack.pop_back();
|
||||
stack.pop_back();
|
||||
stack.pop_back();
|
||||
popstack(stack);
|
||||
popstack(stack);
|
||||
popstack(stack);
|
||||
stack.push_back(fValue ? vchTrue : vchFalse);
|
||||
}
|
||||
break;
|
||||
@@ -718,7 +719,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
||||
uint256 hash = Hash(vch.begin(), vch.end());
|
||||
memcpy(&vchHash[0], &hash, sizeof(hash));
|
||||
}
|
||||
stack.pop_back();
|
||||
popstack(stack);
|
||||
stack.push_back(vchHash);
|
||||
}
|
||||
break;
|
||||
@@ -752,13 +753,13 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
||||
|
||||
bool fSuccess = CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType);
|
||||
|
||||
stack.pop_back();
|
||||
stack.pop_back();
|
||||
popstack(stack);
|
||||
popstack(stack);
|
||||
stack.push_back(fSuccess ? vchTrue : vchFalse);
|
||||
if (opcode == OP_CHECKSIGVERIFY)
|
||||
{
|
||||
if (fSuccess)
|
||||
stack.pop_back();
|
||||
popstack(stack);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
@@ -775,7 +776,10 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
||||
return false;
|
||||
|
||||
int nKeysCount = CastToBigNum(stacktop(-i)).getint();
|
||||
if (nKeysCount < 0)
|
||||
if (nKeysCount < 0 || nKeysCount > 20)
|
||||
return false;
|
||||
nOpCount += nKeysCount;
|
||||
if (nOpCount > 201)
|
||||
return false;
|
||||
int ikey = ++i;
|
||||
i += nKeysCount;
|
||||
@@ -822,13 +826,13 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
||||
}
|
||||
|
||||
while (i-- > 0)
|
||||
stack.pop_back();
|
||||
popstack(stack);
|
||||
stack.push_back(fSuccess ? vchTrue : vchFalse);
|
||||
|
||||
if (opcode == OP_CHECKMULTISIGVERIFY)
|
||||
{
|
||||
if (fSuccess)
|
||||
stack.pop_back();
|
||||
popstack(stack);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
@@ -856,8 +860,6 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
||||
return true;
|
||||
}
|
||||
|
||||
#undef top
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -945,10 +947,7 @@ bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> vchPubKey, CSc
|
||||
return false;
|
||||
vchSig.pop_back();
|
||||
|
||||
if (key.Verify(SignatureHash(scriptCode, txTo, nIn, nHashType), vchSig))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return key.Verify(SignatureHash(scriptCode, txTo, nIn, nHashType), vchSig);
|
||||
}
|
||||
|
||||
|
||||
@@ -986,21 +985,19 @@ bool Solver(const CScript& scriptPubKey, vector<pair<opcodetype, valtype> >& vSo
|
||||
CScript::const_iterator pc2 = script2.begin();
|
||||
loop
|
||||
{
|
||||
bool f1 = script1.GetOp(pc1, opcode1, vch1);
|
||||
bool f2 = script2.GetOp(pc2, opcode2, vch2);
|
||||
if (!f1 && !f2)
|
||||
if (pc1 == script1.end() && pc2 == script2.end())
|
||||
{
|
||||
// Success
|
||||
// Found a match
|
||||
reverse(vSolutionRet.begin(), vSolutionRet.end());
|
||||
return true;
|
||||
}
|
||||
else if (f1 != f2)
|
||||
{
|
||||
if (!script1.GetOp(pc1, opcode1, vch1))
|
||||
break;
|
||||
}
|
||||
else if (opcode2 == OP_PUBKEY)
|
||||
if (!script2.GetOp(pc2, opcode2, vch2))
|
||||
break;
|
||||
if (opcode2 == OP_PUBKEY)
|
||||
{
|
||||
if (vch1.size() <= sizeof(uint256))
|
||||
if (vch1.size() < 33 || vch1.size() > 120)
|
||||
break;
|
||||
vSolutionRet.push_back(make_pair(opcode2, vch1));
|
||||
}
|
||||
@@ -1010,7 +1007,7 @@ bool Solver(const CScript& scriptPubKey, vector<pair<opcodetype, valtype> >& vSo
|
||||
break;
|
||||
vSolutionRet.push_back(make_pair(opcode2, vch1));
|
||||
}
|
||||
else if (opcode1 != opcode2)
|
||||
else if (opcode1 != opcode2 || vch1 != vch2)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -1068,6 +1065,10 @@ bool Solver(const CScript& scriptPubKey, uint256 hash, int nHashType, CScript& s
|
||||
scriptSigRet << vchSig << vchPubKey;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1075,6 +1076,13 @@ bool Solver(const CScript& scriptPubKey, uint256 hash, int nHashType, CScript& s
|
||||
}
|
||||
|
||||
|
||||
bool IsStandard(const CScript& scriptPubKey)
|
||||
{
|
||||
vector<pair<opcodetype, valtype> > vSolution;
|
||||
return Solver(scriptPubKey, vSolution);
|
||||
}
|
||||
|
||||
|
||||
bool IsMine(const CScript& scriptPubKey)
|
||||
{
|
||||
CScript scriptSig;
|
||||
|
||||
196
script.h
196
script.h
@@ -150,18 +150,11 @@ enum opcodetype
|
||||
|
||||
|
||||
|
||||
|
||||
// multi-byte opcodes
|
||||
OP_SINGLEBYTE_END = 0xF0,
|
||||
OP_DOUBLEBYTE_BEGIN = 0xF000,
|
||||
|
||||
// template matching params
|
||||
OP_PUBKEY,
|
||||
OP_PUBKEYHASH,
|
||||
OP_PUBKEYHASH = 0xfd,
|
||||
OP_PUBKEY = 0xfe,
|
||||
|
||||
|
||||
|
||||
OP_INVALIDOPCODE = 0xFFFF,
|
||||
OP_INVALIDOPCODE = 0xff,
|
||||
};
|
||||
|
||||
|
||||
@@ -304,16 +297,13 @@ inline const char* GetOpName(opcodetype opcode)
|
||||
|
||||
|
||||
|
||||
// multi-byte opcodes
|
||||
case OP_SINGLEBYTE_END : return "OP_SINGLEBYTE_END";
|
||||
case OP_DOUBLEBYTE_BEGIN : return "OP_DOUBLEBYTE_BEGIN";
|
||||
case OP_PUBKEY : return "OP_PUBKEY";
|
||||
// template matching params
|
||||
case OP_PUBKEYHASH : return "OP_PUBKEYHASH";
|
||||
|
||||
case OP_PUBKEY : return "OP_PUBKEY";
|
||||
|
||||
case OP_INVALIDOPCODE : return "OP_INVALIDOPCODE";
|
||||
default:
|
||||
return "UNKNOWN_OPCODE";
|
||||
return "OP_UNKNOWN";
|
||||
}
|
||||
};
|
||||
|
||||
@@ -325,8 +315,7 @@ inline string ValueString(const vector<unsigned char>& vch)
|
||||
if (vch.size() <= 4)
|
||||
return strprintf("%d", CBigNum(vch).getint());
|
||||
else
|
||||
return HexNumStr(vch.begin(), vch.end());
|
||||
//return string("(") + HexStr(vch.begin(), vch.end()) + string(")");
|
||||
return HexStr(vch);
|
||||
}
|
||||
|
||||
inline string StackString(const vector<vector<unsigned char> >& vStack)
|
||||
@@ -363,12 +352,12 @@ protected:
|
||||
CBigNum bn(n);
|
||||
*this << bn.getvch();
|
||||
}
|
||||
return (*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CScript& push_uint64(uint64 n)
|
||||
{
|
||||
if (n == -1 || (n >= 1 && n <= 16))
|
||||
if (n >= 1 && n <= 16)
|
||||
{
|
||||
push_back(n + (OP_1 - 1));
|
||||
}
|
||||
@@ -377,7 +366,7 @@ protected:
|
||||
CBigNum bn(n);
|
||||
*this << bn.getvch();
|
||||
}
|
||||
return (*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -398,7 +387,7 @@ public:
|
||||
{
|
||||
CScript ret = a;
|
||||
ret += b;
|
||||
return (ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -419,50 +408,43 @@ public:
|
||||
explicit CScript(const vector<unsigned char>& b) { operator<<(b); }
|
||||
|
||||
|
||||
CScript& operator<<(char b) { return (push_int64(b)); }
|
||||
CScript& operator<<(short b) { return (push_int64(b)); }
|
||||
CScript& operator<<(int b) { return (push_int64(b)); }
|
||||
CScript& operator<<(long b) { return (push_int64(b)); }
|
||||
CScript& operator<<(int64 b) { return (push_int64(b)); }
|
||||
CScript& operator<<(unsigned char b) { return (push_uint64(b)); }
|
||||
CScript& operator<<(unsigned int b) { return (push_uint64(b)); }
|
||||
CScript& operator<<(unsigned short b) { return (push_uint64(b)); }
|
||||
CScript& operator<<(unsigned long b) { return (push_uint64(b)); }
|
||||
CScript& operator<<(uint64 b) { return (push_uint64(b)); }
|
||||
CScript& operator<<(char b) { return push_int64(b); }
|
||||
CScript& operator<<(short b) { return push_int64(b); }
|
||||
CScript& operator<<(int b) { return push_int64(b); }
|
||||
CScript& operator<<(long b) { return push_int64(b); }
|
||||
CScript& operator<<(int64 b) { return push_int64(b); }
|
||||
CScript& operator<<(unsigned char b) { return push_uint64(b); }
|
||||
CScript& operator<<(unsigned int b) { return push_uint64(b); }
|
||||
CScript& operator<<(unsigned short b) { return push_uint64(b); }
|
||||
CScript& operator<<(unsigned long b) { return push_uint64(b); }
|
||||
CScript& operator<<(uint64 b) { return push_uint64(b); }
|
||||
|
||||
CScript& operator<<(opcodetype opcode)
|
||||
{
|
||||
if (opcode <= OP_SINGLEBYTE_END)
|
||||
{
|
||||
insert(end(), (unsigned char)opcode);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(opcode >= OP_DOUBLEBYTE_BEGIN);
|
||||
insert(end(), (unsigned char)(opcode >> 8));
|
||||
insert(end(), (unsigned char)(opcode & 0xFF));
|
||||
}
|
||||
return (*this);
|
||||
if (opcode < 0 || opcode > 0xff)
|
||||
throw runtime_error("CScript::operator<<() : invalid opcode");
|
||||
insert(end(), (unsigned char)opcode);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CScript& operator<<(const uint160& b)
|
||||
{
|
||||
insert(end(), sizeof(b));
|
||||
insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b));
|
||||
return (*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CScript& operator<<(const uint256& b)
|
||||
{
|
||||
insert(end(), sizeof(b));
|
||||
insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b));
|
||||
return (*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CScript& operator<<(const CBigNum& b)
|
||||
{
|
||||
*this << b.getvch();
|
||||
return (*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CScript& operator<<(const vector<unsigned char>& b)
|
||||
@@ -476,14 +458,20 @@ public:
|
||||
insert(end(), OP_PUSHDATA1);
|
||||
insert(end(), (unsigned char)b.size());
|
||||
}
|
||||
else
|
||||
else if (b.size() <= 0xffff)
|
||||
{
|
||||
insert(end(), OP_PUSHDATA2);
|
||||
unsigned short nSize = b.size();
|
||||
insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize));
|
||||
}
|
||||
else
|
||||
{
|
||||
insert(end(), OP_PUSHDATA4);
|
||||
unsigned int nSize = b.size();
|
||||
insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize));
|
||||
}
|
||||
insert(end(), b.begin(), b.end());
|
||||
return (*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CScript& operator<<(const CScript& b)
|
||||
@@ -491,7 +479,7 @@ public:
|
||||
// I'm not sure if this should push the script or concatenate scripts.
|
||||
// If there's ever a use for pushing a script onto a script, delete this member fn
|
||||
assert(("warning: pushing a CScript onto a CScript with << is probably not intended, use + to concatenate", false));
|
||||
return (*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@@ -499,41 +487,59 @@ public:
|
||||
{
|
||||
// Wrapper so it can be called with either iterator or const_iterator
|
||||
const_iterator pc2 = pc;
|
||||
bool fRet = GetOp(pc2, opcodeRet, vchRet);
|
||||
bool fRet = GetOp2(pc2, opcodeRet, &vchRet);
|
||||
pc = begin() + (pc2 - begin());
|
||||
return fRet;
|
||||
}
|
||||
|
||||
bool GetOp(iterator& pc, opcodetype& opcodeRet)
|
||||
{
|
||||
const_iterator pc2 = pc;
|
||||
bool fRet = GetOp2(pc2, opcodeRet, NULL);
|
||||
pc = begin() + (pc2 - begin());
|
||||
return fRet;
|
||||
}
|
||||
|
||||
bool GetOp(const_iterator& pc, opcodetype& opcodeRet, vector<unsigned char>& vchRet) const
|
||||
{
|
||||
return GetOp2(pc, opcodeRet, &vchRet);
|
||||
}
|
||||
|
||||
bool GetOp(const_iterator& pc, opcodetype& opcodeRet) const
|
||||
{
|
||||
return GetOp2(pc, opcodeRet, NULL);
|
||||
}
|
||||
|
||||
bool GetOp2(const_iterator& pc, opcodetype& opcodeRet, vector<unsigned char>* pvchRet) const
|
||||
{
|
||||
opcodeRet = OP_INVALIDOPCODE;
|
||||
vchRet.clear();
|
||||
if (pvchRet)
|
||||
pvchRet->clear();
|
||||
if (pc >= end())
|
||||
return false;
|
||||
|
||||
// Read instruction
|
||||
if (end() - pc < 1)
|
||||
return false;
|
||||
unsigned int opcode = *pc++;
|
||||
if (opcode >= OP_SINGLEBYTE_END)
|
||||
{
|
||||
if (pc + 1 > end())
|
||||
return false;
|
||||
opcode <<= 8;
|
||||
opcode |= *pc++;
|
||||
}
|
||||
|
||||
// Immediate operand
|
||||
if (opcode <= OP_PUSHDATA4)
|
||||
{
|
||||
unsigned int nSize = opcode;
|
||||
if (opcode == OP_PUSHDATA1)
|
||||
unsigned int nSize;
|
||||
if (opcode < OP_PUSHDATA1)
|
||||
{
|
||||
if (pc + 1 > end())
|
||||
nSize = opcode;
|
||||
}
|
||||
else if (opcode == OP_PUSHDATA1)
|
||||
{
|
||||
if (end() - pc < 1)
|
||||
return false;
|
||||
nSize = *pc++;
|
||||
}
|
||||
else if (opcode == OP_PUSHDATA2)
|
||||
{
|
||||
if (pc + 2 > end())
|
||||
if (end() - pc < 2)
|
||||
return false;
|
||||
nSize = 0;
|
||||
memcpy(&nSize, &pc[0], 2);
|
||||
@@ -541,14 +547,15 @@ public:
|
||||
}
|
||||
else if (opcode == OP_PUSHDATA4)
|
||||
{
|
||||
if (pc + 4 > end())
|
||||
if (end() - pc < 4)
|
||||
return false;
|
||||
memcpy(&nSize, &pc[0], 4);
|
||||
pc += 4;
|
||||
}
|
||||
if (pc + nSize > end())
|
||||
if (end() - pc < nSize)
|
||||
return false;
|
||||
vchRet.assign(pc, pc + nSize);
|
||||
if (pvchRet)
|
||||
pvchRet->assign(pc, pc + nSize);
|
||||
pc += nSize;
|
||||
}
|
||||
|
||||
@@ -559,20 +566,51 @@ public:
|
||||
|
||||
void FindAndDelete(const CScript& b)
|
||||
{
|
||||
if (b.empty())
|
||||
return;
|
||||
iterator pc = begin();
|
||||
opcodetype opcode;
|
||||
vector<unsigned char> vchPushValue;
|
||||
int count = 0;
|
||||
do
|
||||
{
|
||||
while (end() - pc >= b.size() && memcmp(&pc[0], &b[0], b.size()) == 0)
|
||||
{
|
||||
erase(pc, pc + b.size());
|
||||
count++;
|
||||
}
|
||||
}
|
||||
while (GetOp(pc, opcode, vchPushValue));
|
||||
//printf("FindAndDeleted deleted %d items\n", count); /// debug
|
||||
while (GetOp(pc, opcode));
|
||||
}
|
||||
|
||||
|
||||
int GetSigOpCount() const
|
||||
{
|
||||
int n = 0;
|
||||
const_iterator pc = begin();
|
||||
while (pc < end())
|
||||
{
|
||||
opcodetype opcode;
|
||||
if (!GetOp(pc, opcode))
|
||||
break;
|
||||
if (opcode == OP_CHECKSIG || opcode == OP_CHECKSIGVERIFY)
|
||||
n++;
|
||||
else if (opcode == OP_CHECKMULTISIG || opcode == OP_CHECKMULTISIGVERIFY)
|
||||
n += 20;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
bool IsPushOnly() const
|
||||
{
|
||||
if (size() > 200)
|
||||
return false;
|
||||
const_iterator pc = begin();
|
||||
while (pc < end())
|
||||
{
|
||||
opcodetype opcode;
|
||||
if (!GetOp(pc, opcode))
|
||||
return false;
|
||||
if (opcode > OP_16)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -623,7 +661,7 @@ public:
|
||||
|
||||
void PrintHex() const
|
||||
{
|
||||
printf("CScript(%s)\n", HexStr(begin(), end()).c_str());
|
||||
printf("CScript(%s)\n", HexStr(begin(), end(), true).c_str());
|
||||
}
|
||||
|
||||
string ToString() const
|
||||
@@ -631,12 +669,17 @@ public:
|
||||
string str;
|
||||
opcodetype opcode;
|
||||
vector<unsigned char> vch;
|
||||
const_iterator it = begin();
|
||||
while (GetOp(it, opcode, vch))
|
||||
const_iterator pc = begin();
|
||||
while (pc < end())
|
||||
{
|
||||
if (!str.empty())
|
||||
str += " ";
|
||||
if (opcode <= OP_PUSHDATA4)
|
||||
if (!GetOp(pc, opcode, vch))
|
||||
{
|
||||
str += "[error]";
|
||||
return str;
|
||||
}
|
||||
if (0 <= opcode && opcode <= OP_PUSHDATA4)
|
||||
str += ValueString(vch);
|
||||
else
|
||||
str += GetOpName(opcode);
|
||||
@@ -658,6 +701,7 @@ public:
|
||||
|
||||
|
||||
uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
|
||||
bool IsStandard(const CScript& scriptPubKey);
|
||||
bool IsMine(const CScript& scriptPubKey);
|
||||
bool ExtractPubKey(const CScript& scriptPubKey, bool fMineOnly, vector<unsigned char>& vchPubKeyRet);
|
||||
bool ExtractHash160(const CScript& scriptPubKey, uint160& hash160Ret);
|
||||
|
||||
140
serialize.h
140
serialize.h
@@ -7,6 +7,9 @@
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <boost/type_traits/is_fundamental.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/tuple/tuple_comparison.hpp>
|
||||
#include <boost/tuple/tuple_io.hpp>
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
typedef __int64 int64;
|
||||
typedef unsigned __int64 uint64;
|
||||
@@ -22,8 +25,8 @@ class CDataStream;
|
||||
class CAutoFile;
|
||||
static const unsigned int MAX_SIZE = 0x02000000;
|
||||
|
||||
static const int VERSION = 312;
|
||||
static const char* pszSubVer = ".0";
|
||||
static const int VERSION = 31800;
|
||||
static const char* pszSubVer = "";
|
||||
|
||||
|
||||
|
||||
@@ -85,13 +88,6 @@ enum
|
||||
|
||||
#define READWRITE(obj) (nSerSize += ::SerReadWrite(s, (obj), nType, nVersion, ser_action))
|
||||
|
||||
#define READWRITEVER(obj) \
|
||||
do { \
|
||||
READWRITE((obj)); \
|
||||
if ((obj) == 10300) \
|
||||
(obj) = 300; \
|
||||
} while (false)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -163,7 +159,7 @@ template<typename Stream> inline void Unserialize(Stream& s, bool& a, int, int=0
|
||||
//
|
||||
inline unsigned int GetSizeOfCompactSize(uint64 nSize)
|
||||
{
|
||||
if (nSize < UCHAR_MAX-2) return sizeof(unsigned char);
|
||||
if (nSize < 253) return sizeof(unsigned char);
|
||||
else if (nSize <= USHRT_MAX) return sizeof(unsigned char) + sizeof(unsigned short);
|
||||
else if (nSize <= UINT_MAX) return sizeof(unsigned char) + sizeof(unsigned int);
|
||||
else return sizeof(unsigned char) + sizeof(uint64);
|
||||
@@ -172,30 +168,31 @@ inline unsigned int GetSizeOfCompactSize(uint64 nSize)
|
||||
template<typename Stream>
|
||||
void WriteCompactSize(Stream& os, uint64 nSize)
|
||||
{
|
||||
if (nSize < UCHAR_MAX-2)
|
||||
if (nSize < 253)
|
||||
{
|
||||
unsigned char chSize = nSize;
|
||||
WRITEDATA(os, chSize);
|
||||
}
|
||||
else if (nSize <= USHRT_MAX)
|
||||
{
|
||||
unsigned char chSize = UCHAR_MAX-2;
|
||||
unsigned char chSize = 253;
|
||||
unsigned short xSize = nSize;
|
||||
WRITEDATA(os, chSize);
|
||||
WRITEDATA(os, xSize);
|
||||
}
|
||||
else if (nSize <= UINT_MAX)
|
||||
{
|
||||
unsigned char chSize = UCHAR_MAX-1;
|
||||
unsigned char chSize = 254;
|
||||
unsigned int xSize = nSize;
|
||||
WRITEDATA(os, chSize);
|
||||
WRITEDATA(os, xSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char chSize = UCHAR_MAX;
|
||||
unsigned char chSize = 255;
|
||||
uint64 xSize = nSize;
|
||||
WRITEDATA(os, chSize);
|
||||
WRITEDATA(os, nSize);
|
||||
WRITEDATA(os, xSize);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -206,27 +203,27 @@ uint64 ReadCompactSize(Stream& is)
|
||||
unsigned char chSize;
|
||||
READDATA(is, chSize);
|
||||
uint64 nSizeRet = 0;
|
||||
if (chSize < UCHAR_MAX-2)
|
||||
if (chSize < 253)
|
||||
{
|
||||
nSizeRet = chSize;
|
||||
}
|
||||
else if (chSize == UCHAR_MAX-2)
|
||||
else if (chSize == 253)
|
||||
{
|
||||
unsigned short nSize;
|
||||
READDATA(is, nSize);
|
||||
nSizeRet = nSize;
|
||||
unsigned short xSize;
|
||||
READDATA(is, xSize);
|
||||
nSizeRet = xSize;
|
||||
}
|
||||
else if (chSize == UCHAR_MAX-1)
|
||||
else if (chSize == 254)
|
||||
{
|
||||
unsigned int nSize;
|
||||
READDATA(is, nSize);
|
||||
nSizeRet = nSize;
|
||||
unsigned int xSize;
|
||||
READDATA(is, xSize);
|
||||
nSizeRet = xSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64 nSize;
|
||||
READDATA(is, nSize);
|
||||
nSizeRet = nSize;
|
||||
uint64 xSize;
|
||||
READDATA(is, xSize);
|
||||
nSizeRet = xSize;
|
||||
}
|
||||
if (nSizeRet > (uint64)MAX_SIZE)
|
||||
throw std::ios_base::failure("ReadCompactSize() : size too large");
|
||||
@@ -344,6 +341,16 @@ template<typename K, typename T> unsigned int GetSerializeSize(const std::pair<K
|
||||
template<typename Stream, typename K, typename T> void Serialize(Stream& os, const std::pair<K, T>& item, int nType, int nVersion=VERSION);
|
||||
template<typename Stream, typename K, typename T> void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion=VERSION);
|
||||
|
||||
// 3 tuple
|
||||
template<typename T0, typename T1, typename T2> unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2>& item, int nType, int nVersion=VERSION);
|
||||
template<typename Stream, typename T0, typename T1, typename T2> void Serialize(Stream& os, const boost::tuple<T0, T1, T2>& item, int nType, int nVersion=VERSION);
|
||||
template<typename Stream, typename T0, typename T1, typename T2> void Unserialize(Stream& is, boost::tuple<T0, T1, T2>& item, int nType, int nVersion=VERSION);
|
||||
|
||||
// 4 tuple
|
||||
template<typename T0, typename T1, typename T2, typename T3> unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion=VERSION);
|
||||
template<typename Stream, typename T0, typename T1, typename T2, typename T3> void Serialize(Stream& os, const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion=VERSION);
|
||||
template<typename Stream, typename T0, typename T1, typename T2, typename T3> void Unserialize(Stream& is, boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion=VERSION);
|
||||
|
||||
// map
|
||||
template<typename K, typename T, typename Pred, typename A> unsigned int GetSerializeSize(const std::map<K, T, Pred, A>& m, int nType, int nVersion=VERSION);
|
||||
template<typename Stream, typename K, typename T, typename Pred, typename A> void Serialize(Stream& os, const std::map<K, T, Pred, A>& m, int nType, int nVersion=VERSION);
|
||||
@@ -560,6 +567,71 @@ void Unserialize(Stream& is, std::pair<K, T>& item, int nType, int nVersion)
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 3 tuple
|
||||
//
|
||||
template<typename T0, typename T1, typename T2>
|
||||
unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2>& item, int nType, int nVersion)
|
||||
{
|
||||
unsigned int nSize = 0;
|
||||
nSize += GetSerializeSize(get<0>(item), nType, nVersion);
|
||||
nSize += GetSerializeSize(get<1>(item), nType, nVersion);
|
||||
nSize += GetSerializeSize(get<2>(item), nType, nVersion);
|
||||
return nSize;
|
||||
}
|
||||
|
||||
template<typename Stream, typename T0, typename T1, typename T2>
|
||||
void Serialize(Stream& os, const boost::tuple<T0, T1, T2>& item, int nType, int nVersion)
|
||||
{
|
||||
Serialize(os, get<0>(item), nType, nVersion);
|
||||
Serialize(os, get<1>(item), nType, nVersion);
|
||||
Serialize(os, get<2>(item), nType, nVersion);
|
||||
}
|
||||
|
||||
template<typename Stream, typename T0, typename T1, typename T2>
|
||||
void Unserialize(Stream& is, boost::tuple<T0, T1, T2>& item, int nType, int nVersion)
|
||||
{
|
||||
Unserialize(is, get<0>(item), nType, nVersion);
|
||||
Unserialize(is, get<1>(item), nType, nVersion);
|
||||
Unserialize(is, get<2>(item), nType, nVersion);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// 4 tuple
|
||||
//
|
||||
template<typename T0, typename T1, typename T2, typename T3>
|
||||
unsigned int GetSerializeSize(const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion)
|
||||
{
|
||||
unsigned int nSize = 0;
|
||||
nSize += GetSerializeSize(get<0>(item), nType, nVersion);
|
||||
nSize += GetSerializeSize(get<1>(item), nType, nVersion);
|
||||
nSize += GetSerializeSize(get<2>(item), nType, nVersion);
|
||||
nSize += GetSerializeSize(get<3>(item), nType, nVersion);
|
||||
return nSize;
|
||||
}
|
||||
|
||||
template<typename Stream, typename T0, typename T1, typename T2, typename T3>
|
||||
void Serialize(Stream& os, const boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion)
|
||||
{
|
||||
Serialize(os, get<0>(item), nType, nVersion);
|
||||
Serialize(os, get<1>(item), nType, nVersion);
|
||||
Serialize(os, get<2>(item), nType, nVersion);
|
||||
Serialize(os, get<3>(item), nType, nVersion);
|
||||
}
|
||||
|
||||
template<typename Stream, typename T0, typename T1, typename T2, typename T3>
|
||||
void Unserialize(Stream& is, boost::tuple<T0, T1, T2, T3>& item, int nType, int nVersion)
|
||||
{
|
||||
Unserialize(is, get<0>(item), nType, nVersion);
|
||||
Unserialize(is, get<1>(item), nType, nVersion);
|
||||
Unserialize(is, get<2>(item), nType, nVersion);
|
||||
Unserialize(is, get<3>(item), nType, nVersion);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// map
|
||||
//
|
||||
@@ -731,39 +803,39 @@ public:
|
||||
typedef vector_type::const_iterator const_iterator;
|
||||
typedef vector_type::reverse_iterator reverse_iterator;
|
||||
|
||||
explicit CDataStream(int nTypeIn=0, int nVersionIn=VERSION)
|
||||
explicit CDataStream(int nTypeIn=SER_NETWORK, int nVersionIn=VERSION)
|
||||
{
|
||||
Init(nTypeIn, nVersionIn);
|
||||
}
|
||||
|
||||
CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn=0, int nVersionIn=VERSION) : vch(pbegin, pend)
|
||||
CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(pbegin, pend)
|
||||
{
|
||||
Init(nTypeIn, nVersionIn);
|
||||
}
|
||||
|
||||
#if !defined(_MSC_VER) || _MSC_VER >= 1300
|
||||
CDataStream(const char* pbegin, const char* pend, int nTypeIn=0, int nVersionIn=VERSION) : vch(pbegin, pend)
|
||||
CDataStream(const char* pbegin, const char* pend, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(pbegin, pend)
|
||||
{
|
||||
Init(nTypeIn, nVersionIn);
|
||||
}
|
||||
#endif
|
||||
|
||||
CDataStream(const vector_type& vchIn, int nTypeIn=0, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end())
|
||||
CDataStream(const vector_type& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end())
|
||||
{
|
||||
Init(nTypeIn, nVersionIn);
|
||||
}
|
||||
|
||||
CDataStream(const vector<char>& vchIn, int nTypeIn=0, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end())
|
||||
CDataStream(const vector<char>& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end())
|
||||
{
|
||||
Init(nTypeIn, nVersionIn);
|
||||
}
|
||||
|
||||
CDataStream(const vector<unsigned char>& vchIn, int nTypeIn=0, int nVersionIn=VERSION) : vch((char*)&vchIn.begin()[0], (char*)&vchIn.end()[0])
|
||||
CDataStream(const vector<unsigned char>& vchIn, int nTypeIn=SER_NETWORK, int nVersionIn=VERSION) : vch((char*)&vchIn.begin()[0], (char*)&vchIn.end()[0])
|
||||
{
|
||||
Init(nTypeIn, nVersionIn);
|
||||
}
|
||||
|
||||
void Init(int nTypeIn=0, int nVersionIn=VERSION)
|
||||
void Init(int nTypeIn=SER_NETWORK, int nVersionIn=VERSION)
|
||||
{
|
||||
nReadPos = 0;
|
||||
nType = nTypeIn;
|
||||
|
||||
@@ -7,7 +7,7 @@ RequestExecutionLevel highest
|
||||
|
||||
# General Symbol Definitions
|
||||
!define REGKEY "SOFTWARE\$(^Name)"
|
||||
!define VERSION 0.3.10
|
||||
!define VERSION 0.3.18
|
||||
!define COMPANY "Bitcoin project"
|
||||
!define URL http://www.bitcoin.org/
|
||||
|
||||
@@ -42,12 +42,12 @@ Var StartMenuGroup
|
||||
!insertmacro MUI_LANGUAGE English
|
||||
|
||||
# Installer attributes
|
||||
OutFile bitcoin-0.3.10-win32-setup.exe
|
||||
OutFile bitcoin-0.3.18-win32-setup.exe
|
||||
InstallDir $PROGRAMFILES\Bitcoin
|
||||
CRCCheck on
|
||||
XPStyle on
|
||||
ShowInstDetails show
|
||||
VIProductVersion 0.3.10.0
|
||||
VIProductVersion 0.3.18.0
|
||||
VIAddVersionKey ProductName Bitcoin
|
||||
VIAddVersionKey ProductVersion "${VERSION}"
|
||||
VIAddVersionKey CompanyName "${COMPANY}"
|
||||
|
||||
56
sha256.cpp
56
sha256.cpp
@@ -1,7 +1,9 @@
|
||||
// Copyright (c) 2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2010 Nils Schneider
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
// 4-way 128-bit SSE2 SHA-256
|
||||
|
||||
#ifdef FOURWAYSSE2
|
||||
|
||||
#include <string.h>
|
||||
@@ -13,6 +15,8 @@
|
||||
|
||||
#define NPAR 32
|
||||
|
||||
extern void DoubleBlockSHA256(const void* pin, void* pout, const void* pinit, unsigned int hash[8][NPAR], const void* init2);
|
||||
|
||||
static const unsigned int sha256_consts[] = {
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, /* 0 */
|
||||
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||
@@ -87,7 +91,55 @@ static inline void dumpreg(__m128i x, char *msg) {
|
||||
#else
|
||||
#define dumpstate()
|
||||
#endif
|
||||
void Double_BlockSHA256(const void* pin, void* pad, const void *pre, unsigned int thash[9][NPAR], const void *init)
|
||||
|
||||
// Align by increasing pointer, must have extra space at end of buffer
|
||||
template <size_t nBytes, typename T>
|
||||
T* alignup(T* p)
|
||||
{
|
||||
union
|
||||
{
|
||||
T* ptr;
|
||||
size_t n;
|
||||
} u;
|
||||
u.ptr = p;
|
||||
u.n = (u.n + (nBytes-1)) & ~(nBytes-1);
|
||||
return u.ptr;
|
||||
}
|
||||
|
||||
static const unsigned int pSHA256InitState[8] =
|
||||
{0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
|
||||
|
||||
|
||||
unsigned int ScanHash_4WaySSE2(char* pmidstate, char* pdata, char* phash1, char* phash, unsigned int& nHashesDone)
|
||||
{
|
||||
unsigned int& nNonce = *(unsigned int*)(pdata + 12);
|
||||
for (;;)
|
||||
{
|
||||
nNonce += NPAR;
|
||||
unsigned int thashbuf[9][NPAR];
|
||||
unsigned int (&thash)[9][NPAR] = *alignup<16>(&thashbuf);
|
||||
DoubleBlockSHA256(pdata, phash1, pmidstate, thash, pSHA256InitState);
|
||||
|
||||
for (int j = 0; j < NPAR; j++)
|
||||
{
|
||||
if (thash[7][j] == 0)
|
||||
{
|
||||
for (int i = 0; i < 32/4; i++)
|
||||
((unsigned int*)phash)[i] = thash[i][j];
|
||||
return nNonce + j;
|
||||
}
|
||||
}
|
||||
|
||||
if ((nNonce & 0xffff) == 0)
|
||||
{
|
||||
nHashesDone = 0xffff+1;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DoubleBlockSHA256(const void* pin, void* pad, const void *pre, unsigned int thash[9][NPAR], const void *init)
|
||||
{
|
||||
unsigned int* In = (unsigned int*)pin;
|
||||
unsigned int* Pad = (unsigned int*)pad;
|
||||
|
||||
220
ui.cpp
220
ui.cpp
@@ -103,6 +103,18 @@ int InsertLine(wxListCtrl* listCtrl, void* pdata, const wxString& str0, const wx
|
||||
return nIndex;
|
||||
}
|
||||
|
||||
void SetItemTextColour(wxListCtrl* listCtrl, int nIndex, const wxColour& colour)
|
||||
{
|
||||
// Repaint on Windows is more flickery if the colour has ever been set,
|
||||
// so don't want to set it unless it's different. Default colour has
|
||||
// alpha 0 transparent, so our colours don't match using operator==.
|
||||
wxColour c1 = listCtrl->GetItemTextColour(nIndex);
|
||||
if (!c1.IsOk())
|
||||
c1 = wxColour(0,0,0);
|
||||
if (colour.Red() != c1.Red() || colour.Green() != c1.Green() || colour.Blue() != c1.Blue())
|
||||
listCtrl->SetItemTextColour(nIndex, colour);
|
||||
}
|
||||
|
||||
void SetSelection(wxListCtrl* listCtrl, int nIndex)
|
||||
{
|
||||
int nSize = listCtrl->GetItemCount();
|
||||
@@ -184,7 +196,7 @@ int ThreadSafeMessageBox(const string& message, const string& caption, int style
|
||||
|
||||
bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* parent)
|
||||
{
|
||||
if (nFeeRequired == 0 || fDaemon)
|
||||
if (nFeeRequired < CENT || nFeeRequired <= nTransactionFee || fDaemon)
|
||||
return true;
|
||||
string strMessage = strprintf(
|
||||
_("This transaction is over the size limit. You can still send it for a fee of %s, "
|
||||
@@ -379,7 +391,7 @@ void CMainFrame::OnIconize(wxIconizeEvent& event)
|
||||
if (!event.Iconized())
|
||||
fClosedToTray = false;
|
||||
#if defined(__WXGTK__) || defined(__WXMAC_OSX__)
|
||||
if (mapArgs.count("-minimizetotray")) {
|
||||
if (GetBoolArg("-minimizetotray")) {
|
||||
#endif
|
||||
// The tray icon sometimes disappears on ubuntu karmic
|
||||
// Hiding the taskbar button doesn't work cleanly on ubuntu lucid
|
||||
@@ -434,7 +446,7 @@ int CMainFrame::GetSortIndex(const string& strSort)
|
||||
#endif
|
||||
}
|
||||
|
||||
void CMainFrame::InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5, const wxString& str6)
|
||||
void CMainFrame::InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxColour& colour, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5, const wxString& str6)
|
||||
{
|
||||
strSort = " " + strSort; // leading space to workaround wx2.9.0 ubuntu 9.10 bug
|
||||
long nData = *(long*)&hashKey; // where first char of hidden column is displayed
|
||||
@@ -470,6 +482,7 @@ void CMainFrame::InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSo
|
||||
m_listCtrl->SetItem(nIndex, 5, str5);
|
||||
m_listCtrl->SetItem(nIndex, 6, str6);
|
||||
m_listCtrl->SetItemData(nIndex, nData);
|
||||
SetItemTextColour(m_listCtrl, nIndex, colour);
|
||||
}
|
||||
|
||||
bool CMainFrame::DeleteLine(uint256 hashKey)
|
||||
@@ -540,6 +553,8 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex)
|
||||
int64 nNet = nCredit - nDebit;
|
||||
uint256 hash = wtx.GetHash();
|
||||
string strStatus = FormatTxStatus(wtx);
|
||||
bool fConfirmed = wtx.fConfirmedDisplayed = wtx.IsConfirmed();
|
||||
wxColour colour = (fConfirmed ? wxColour(0,0,0) : wxColour(128,128,128));
|
||||
map<string, string> mapValue = wtx.mapValue;
|
||||
wtx.nLinesDisplayed = 1;
|
||||
nListViewUpdated++;
|
||||
@@ -658,12 +673,16 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex)
|
||||
}
|
||||
}
|
||||
|
||||
InsertLine(fNew, nIndex, hash, strSort,
|
||||
string strCredit = FormatMoney(nNet, true);
|
||||
if (!fConfirmed)
|
||||
strCredit = "[" + strCredit + "]";
|
||||
|
||||
InsertLine(fNew, nIndex, hash, strSort, colour,
|
||||
strStatus,
|
||||
nTime ? DateTimeStr(nTime) : "",
|
||||
SingleLine(strDescription),
|
||||
"",
|
||||
FormatMoney(nNet, true));
|
||||
strCredit);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -678,16 +697,13 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex)
|
||||
if (fAllFromMe && fAllToMe)
|
||||
{
|
||||
// Payment to self
|
||||
int64 nValue = wtx.vout[0].nValue;
|
||||
InsertLine(fNew, nIndex, hash, strSort,
|
||||
int64 nChange = wtx.GetChange();
|
||||
InsertLine(fNew, nIndex, hash, strSort, colour,
|
||||
strStatus,
|
||||
nTime ? DateTimeStr(nTime) : "",
|
||||
_("Payment to yourself"),
|
||||
"",
|
||||
"");
|
||||
/// issue: can't tell which is the payment and which is the change anymore
|
||||
// FormatMoney(nNet - nValue, true),
|
||||
// FormatMoney(nValue, true));
|
||||
FormatMoney(-(nDebit - nChange), true),
|
||||
FormatMoney(nCredit - nChange, true));
|
||||
}
|
||||
else if (fAllFromMe)
|
||||
{
|
||||
@@ -738,12 +754,13 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex)
|
||||
nTxFee = 0;
|
||||
}
|
||||
|
||||
InsertLine(fNew, nIndex, hash, strprintf("%s-%d", strSort.c_str(), nOut),
|
||||
InsertLine(fNew, nIndex, hash, strprintf("%s-%d", strSort.c_str(), nOut), colour,
|
||||
strStatus,
|
||||
nTime ? DateTimeStr(nTime) : "",
|
||||
SingleLine(strDescription),
|
||||
FormatMoney(-nValue, true),
|
||||
"");
|
||||
nIndex = -1;
|
||||
wtx.nLinesDisplayed++;
|
||||
}
|
||||
}
|
||||
@@ -758,7 +775,7 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex)
|
||||
foreach(const CTxIn& txin, wtx.vin)
|
||||
fAllMine = fAllMine && txin.IsMine();
|
||||
|
||||
InsertLine(fNew, nIndex, hash, strSort,
|
||||
InsertLine(fNew, nIndex, hash, strSort, colour,
|
||||
strStatus,
|
||||
nTime ? DateTimeStr(nTime) : "",
|
||||
"",
|
||||
@@ -885,13 +902,17 @@ void CMainFrame::RefreshStatusColumn()
|
||||
continue;
|
||||
}
|
||||
CWalletTx& wtx = (*mi).second;
|
||||
if (wtx.IsCoinBase() || wtx.GetTxTime() != wtx.nTimeDisplayed)
|
||||
if (wtx.IsCoinBase() ||
|
||||
wtx.GetTxTime() != wtx.nTimeDisplayed ||
|
||||
wtx.IsConfirmed() != wtx.fConfirmedDisplayed)
|
||||
{
|
||||
if (!InsertTransaction(wtx, false, nIndex))
|
||||
m_listCtrl->DeleteItem(nIndex--);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_listCtrl->SetItem(nIndex, 2, FormatTxStatus(wtx));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1031,9 +1052,6 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event)
|
||||
string strStatus = strprintf(_(" %d connections %d blocks %d transactions"), vNodes.size(), nBestHeight, nTransactionCount);
|
||||
m_statusBar->SetStatusText(strStatus, 2);
|
||||
|
||||
if (fDebug && GetTime() - nThreadSocketHandlerHeartbeat > 60)
|
||||
m_statusBar->SetStatusText(" ERROR: ThreadSocketHandler has stopped", 0);
|
||||
|
||||
// Update receiving address
|
||||
string strDefaultAddress = PubKeyToAddress(vchDefaultKey);
|
||||
if (m_textCtrlAddress->GetValue() != strDefaultAddress)
|
||||
@@ -1150,7 +1168,7 @@ void CMainFrame::OnButtonNew(wxCommandEvent& event)
|
||||
string strName = dialog.GetValue();
|
||||
|
||||
// Generate new key
|
||||
string strAddress = PubKeyToAddress(GenerateNewKey());
|
||||
string strAddress = PubKeyToAddress(GetKeyFromKeyPool());
|
||||
|
||||
// Save
|
||||
SetAddressBookName(strAddress, strName);
|
||||
@@ -1355,10 +1373,10 @@ CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetails
|
||||
if (fAllToMe)
|
||||
{
|
||||
// Payment to self
|
||||
/// issue: can't tell which is the payment and which is the change anymore
|
||||
//int64 nValue = wtx.vout[0].nValue;
|
||||
//strHTML += _("<b>Debit:</b> ") + FormatMoney(-nValue) + "<br>";
|
||||
//strHTML += _("<b>Credit:</b> ") + FormatMoney(nValue) + "<br>";
|
||||
int64 nChange = wtx.GetChange();
|
||||
int64 nValue = nCredit - nChange;
|
||||
strHTML += _("<b>Debit:</b> ") + FormatMoney(-nValue) + "<br>";
|
||||
strHTML += _("<b>Credit:</b> ") + FormatMoney(nValue) + "<br>";
|
||||
}
|
||||
|
||||
int64 nTxFee = nDebit - wtx.GetValueOut();
|
||||
@@ -1405,7 +1423,10 @@ CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetails
|
||||
if (txout.IsMine())
|
||||
strHTML += "<b>Credit:</b> " + FormatMoney(txout.GetCredit()) + "<br>";
|
||||
|
||||
strHTML += "<b>Inputs:</b><br>";
|
||||
strHTML += "<br><b>Transaction:</b><br>";
|
||||
strHTML += HtmlEscape(wtx.ToString(), true);
|
||||
|
||||
strHTML += "<br><b>Inputs:</b><br>";
|
||||
CRITICAL_BLOCK(cs_mapWallet)
|
||||
{
|
||||
foreach(const CTxIn& txin, wtx.vin)
|
||||
@@ -1424,9 +1445,6 @@ CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetails
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
strHTML += "<br><hr><br><b>Transaction:</b><br>";
|
||||
strHTML += HtmlEscape(wtx.ToString(), true);
|
||||
}
|
||||
|
||||
|
||||
@@ -1610,9 +1628,12 @@ COptionsDialog::COptionsDialog(wxWindow* parent) : COptionsDialogBase(parent)
|
||||
//m_listBox->Append(_("Test 2"));
|
||||
m_listBox->SetSelection(0);
|
||||
SelectPage(0);
|
||||
#ifndef __WXMSW__
|
||||
SetSize(1.0 * GetSize().GetWidth(), 1.2 * GetSize().GetHeight());
|
||||
#endif
|
||||
#if defined(__WXGTK__) || defined(__WXMAC_OSX__)
|
||||
m_checkBoxStartOnSystemStartup->SetLabel(_("&Start Bitcoin on window system startup"));
|
||||
if (!mapArgs.count("-minimizetotray"))
|
||||
if (!GetBoolArg("-minimizetotray"))
|
||||
{
|
||||
// Minimize to tray is just too buggy on Linux
|
||||
fMinimizeToTray = false;
|
||||
@@ -1775,7 +1796,7 @@ void COptionsDialog::OnButtonApply(wxCommandEvent& event)
|
||||
|
||||
CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent)
|
||||
{
|
||||
m_staticTextVersion->SetLabel(strprintf(_("version %d.%d.%d%s beta"), VERSION/10000, (VERSION/100)%100, VERSION%100, pszSubVer));
|
||||
m_staticTextVersion->SetLabel(strprintf(_("version %s%s beta"), FormatVersion(VERSION).c_str(), pszSubVer));
|
||||
|
||||
// Change (c) into UTF-8 or ANSI copyright symbol
|
||||
wxString str = m_staticTextMain->GetLabel();
|
||||
@@ -1908,69 +1929,78 @@ void CSendDialog::OnButtonPaste(wxCommandEvent& event)
|
||||
|
||||
void CSendDialog::OnButtonSend(wxCommandEvent& event)
|
||||
{
|
||||
CWalletTx wtx;
|
||||
string strAddress = (string)m_textCtrlAddress->GetValue();
|
||||
static CCriticalSection cs_sendlock;
|
||||
TRY_CRITICAL_BLOCK(cs_sendlock)
|
||||
{
|
||||
CWalletTx wtx;
|
||||
string strAddress = (string)m_textCtrlAddress->GetValue();
|
||||
|
||||
// Parse amount
|
||||
int64 nValue = 0;
|
||||
if (!ParseMoney(m_textCtrlAmount->GetValue(), nValue) || nValue <= 0)
|
||||
{
|
||||
wxMessageBox(_("Error in amount "), _("Send Coins"));
|
||||
return;
|
||||
}
|
||||
if (nValue > GetBalance())
|
||||
{
|
||||
wxMessageBox(_("Amount exceeds your balance "), _("Send Coins"));
|
||||
return;
|
||||
}
|
||||
if (nValue + nTransactionFee > GetBalance())
|
||||
{
|
||||
wxMessageBox(string(_("Total exceeds your balance when the ")) + FormatMoney(nTransactionFee) + _(" transaction fee is included "), _("Send Coins"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse bitcoin address
|
||||
uint160 hash160;
|
||||
bool fBitcoinAddress = AddressToHash160(strAddress, hash160);
|
||||
|
||||
if (fBitcoinAddress)
|
||||
{
|
||||
// Send to bitcoin address
|
||||
CScript scriptPubKey;
|
||||
scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG;
|
||||
|
||||
string strError = SendMoney(scriptPubKey, nValue, wtx, true);
|
||||
if (strError == "")
|
||||
wxMessageBox(_("Payment sent "), _("Sending..."));
|
||||
else if (strError != "ABORTED")
|
||||
wxMessageBox(strError + " ", _("Sending..."));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Parse IP address
|
||||
CAddress addr(strAddress);
|
||||
if (!addr.IsValid())
|
||||
// Parse amount
|
||||
int64 nValue = 0;
|
||||
if (!ParseMoney(m_textCtrlAmount->GetValue(), nValue) || nValue <= 0)
|
||||
{
|
||||
wxMessageBox(_("Invalid address "), _("Send Coins"));
|
||||
wxMessageBox(_("Error in amount "), _("Send Coins"));
|
||||
return;
|
||||
}
|
||||
if (nValue > GetBalance())
|
||||
{
|
||||
wxMessageBox(_("Amount exceeds your balance "), _("Send Coins"));
|
||||
return;
|
||||
}
|
||||
if (nValue + nTransactionFee > GetBalance())
|
||||
{
|
||||
wxMessageBox(string(_("Total exceeds your balance when the ")) + FormatMoney(nTransactionFee) + _(" transaction fee is included "), _("Send Coins"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Message
|
||||
wtx.mapValue["to"] = strAddress;
|
||||
wtx.mapValue["from"] = m_textCtrlFrom->GetValue();
|
||||
wtx.mapValue["message"] = m_textCtrlMessage->GetValue();
|
||||
// Parse bitcoin address
|
||||
uint160 hash160;
|
||||
bool fBitcoinAddress = AddressToHash160(strAddress, hash160);
|
||||
|
||||
// Send to IP address
|
||||
CSendingDialog* pdialog = new CSendingDialog(this, addr, nValue, wtx);
|
||||
if (!pdialog->ShowModal())
|
||||
return;
|
||||
if (fBitcoinAddress)
|
||||
{
|
||||
// Send to bitcoin address
|
||||
CScript scriptPubKey;
|
||||
scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG;
|
||||
|
||||
string strError = SendMoney(scriptPubKey, nValue, wtx, true);
|
||||
if (strError == "")
|
||||
wxMessageBox(_("Payment sent "), _("Sending..."));
|
||||
else if (strError == "ABORTED")
|
||||
return; // leave send dialog open
|
||||
else
|
||||
{
|
||||
wxMessageBox(strError + " ", _("Sending..."));
|
||||
EndModal(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Parse IP address
|
||||
CAddress addr(strAddress);
|
||||
if (!addr.IsValid())
|
||||
{
|
||||
wxMessageBox(_("Invalid address "), _("Send Coins"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Message
|
||||
wtx.mapValue["to"] = strAddress;
|
||||
wtx.mapValue["from"] = m_textCtrlFrom->GetValue();
|
||||
wtx.mapValue["message"] = m_textCtrlMessage->GetValue();
|
||||
|
||||
// Send to IP address
|
||||
CSendingDialog* pdialog = new CSendingDialog(this, addr, nValue, wtx);
|
||||
if (!pdialog->ShowModal())
|
||||
return;
|
||||
}
|
||||
|
||||
CRITICAL_BLOCK(cs_mapAddressBook)
|
||||
if (!mapAddressBook.count(strAddress))
|
||||
SetAddressBookName(strAddress, "");
|
||||
|
||||
EndModal(true);
|
||||
}
|
||||
|
||||
CRITICAL_BLOCK(cs_mapAddressBook)
|
||||
if (!mapAddressBook.count(strAddress))
|
||||
SetAddressBookName(strAddress, "");
|
||||
|
||||
EndModal(true);
|
||||
}
|
||||
|
||||
void CSendDialog::OnButtonCancel(wxCommandEvent& event)
|
||||
@@ -2189,8 +2219,12 @@ void CSendingDialog::OnReply2(CDataStream& vRecv)
|
||||
if (nRet > 0)
|
||||
{
|
||||
string strMessage;
|
||||
vRecv >> strMessage;
|
||||
Error(_("Transfer was not accepted"));
|
||||
if (!vRecv.empty())
|
||||
vRecv >> strMessage;
|
||||
if (nRet == 2)
|
||||
Error(_("Recipient is not accepting transactions sent by IP address"));
|
||||
else
|
||||
Error(_("Transfer was not accepted"));
|
||||
//// todo: enlarge the window and enable a hidden white box to put seller's message
|
||||
return;
|
||||
}
|
||||
@@ -2221,9 +2255,9 @@ void CSendingDialog::OnReply2(CDataStream& vRecv)
|
||||
Error(_("Insufficient funds"));
|
||||
return;
|
||||
}
|
||||
CKey key;
|
||||
CReserveKey reservekey;
|
||||
int64 nFeeRequired;
|
||||
if (!CreateTransaction(scriptPubKey, nPrice, wtx, key, nFeeRequired))
|
||||
if (!CreateTransaction(scriptPubKey, nPrice, wtx, reservekey, nFeeRequired))
|
||||
{
|
||||
if (nPrice + nFeeRequired > GetBalance())
|
||||
Error(strprintf(_("This is an oversized transaction that requires a transaction fee of %s"), FormatMoney(nFeeRequired).c_str()));
|
||||
@@ -2263,7 +2297,7 @@ void CSendingDialog::OnReply2(CDataStream& vRecv)
|
||||
return;
|
||||
|
||||
// Commit
|
||||
if (!CommitTransaction(wtx, key))
|
||||
if (!CommitTransaction(wtx, reservekey))
|
||||
{
|
||||
Error(_("The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."));
|
||||
return;
|
||||
@@ -2541,7 +2575,7 @@ void CAddressBookDialog::OnButtonNew(wxCommandEvent& event)
|
||||
strName = dialog.GetValue();
|
||||
|
||||
// Generate new key
|
||||
strAddress = PubKeyToAddress(GenerateNewKey());
|
||||
strAddress = PubKeyToAddress(GetKeyFromKeyPool());
|
||||
}
|
||||
|
||||
// Add to list and select it
|
||||
@@ -2707,10 +2741,10 @@ wxMenu* CMyTaskBarIcon::CreatePopupMenu()
|
||||
void CreateMainWindow()
|
||||
{
|
||||
pframeMain = new CMainFrame(NULL);
|
||||
if (mapArgs.count("-min"))
|
||||
if (GetBoolArg("-min"))
|
||||
pframeMain->Iconize(true);
|
||||
#if defined(__WXGTK__) || defined(__WXMAC_OSX__)
|
||||
if (!mapArgs.count("-minimizetotray"))
|
||||
if (!GetBoolArg("-minimizetotray"))
|
||||
fMinimizeToTray = false;
|
||||
#endif
|
||||
pframeMain->Show(true); // have to show first to get taskbar button to hide
|
||||
|
||||
7
ui.h
7
ui.h
@@ -11,7 +11,6 @@ extern wxLocale g_locale;
|
||||
|
||||
|
||||
void HandleCtrlA(wxKeyEvent& event);
|
||||
string FormatTxStatus(const CWalletTx& wtx);
|
||||
void UIThreadCall(boost::function0<void>);
|
||||
int ThreadSafeMessageBox(const string& message, const string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1);
|
||||
bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* parent);
|
||||
@@ -96,7 +95,7 @@ public:
|
||||
|
||||
void OnUIThreadCall(wxCommandEvent& event);
|
||||
int GetSortIndex(const string& strSort);
|
||||
void InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5);
|
||||
void InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxColour& colour, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5);
|
||||
bool DeleteLine(uint256 hashKey);
|
||||
bool InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1);
|
||||
void RefreshListCtrl();
|
||||
@@ -305,8 +304,8 @@ public:
|
||||
y += 46 + wxString(strMessage2).Freq('\n') * 14;
|
||||
}
|
||||
#ifndef __WXMSW__
|
||||
x *= 1.14;
|
||||
y *= 1.14;
|
||||
x = x * 114 / 100;
|
||||
y = y * 114 / 100;
|
||||
#endif
|
||||
SetSize(x, y);
|
||||
}
|
||||
|
||||
45
uibase.cpp
45
uibase.cpp
@@ -352,28 +352,6 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w
|
||||
|
||||
bSizer69->Add( 0, 16, 0, wxEXPAND, 5 );
|
||||
|
||||
m_staticText32 = new wxStaticText( m_panelMain, wxID_ANY, _("Optional transaction fee you give to the nodes that process your transactions."), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText32->Wrap( -1 );
|
||||
m_staticText32->Hide();
|
||||
|
||||
bSizer69->Add( m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
wxBoxSizer* bSizer56;
|
||||
bSizer56 = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
m_staticText31 = new wxStaticText( m_panelMain, wxID_ANY, _("Transaction fee:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText31->Wrap( -1 );
|
||||
m_staticText31->Hide();
|
||||
|
||||
bSizer56->Add( m_staticText31, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
|
||||
|
||||
m_textCtrlTransactionFee = new wxTextCtrl( m_panelMain, wxID_TRANSACTIONFEE, wxEmptyString, wxDefaultPosition, wxSize( 70,-1 ), 0 );
|
||||
m_textCtrlTransactionFee->Hide();
|
||||
|
||||
bSizer56->Add( m_textCtrlTransactionFee, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
bSizer69->Add( bSizer56, 0, wxEXPAND, 5 );
|
||||
|
||||
wxBoxSizer* bSizer71;
|
||||
bSizer71 = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
@@ -435,6 +413,25 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w
|
||||
|
||||
bSizer69->Add( bSizer103, 1, wxEXPAND, 5 );
|
||||
|
||||
|
||||
bSizer69->Add( 0, 1, 0, 0, 5 );
|
||||
|
||||
m_staticText32 = new wxStaticText( m_panelMain, wxID_ANY, _("Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended."), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText32->Wrap( 365 );
|
||||
bSizer69->Add( m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
wxBoxSizer* bSizer56;
|
||||
bSizer56 = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
m_staticText31 = new wxStaticText( m_panelMain, wxID_ANY, _("Pay transaction fee:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText31->Wrap( -1 );
|
||||
bSizer56->Add( m_staticText31, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
|
||||
|
||||
m_textCtrlTransactionFee = new wxTextCtrl( m_panelMain, wxID_TRANSACTIONFEE, wxEmptyString, wxDefaultPosition, wxSize( 70,-1 ), 0 );
|
||||
bSizer56->Add( m_textCtrlTransactionFee, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
bSizer69->Add( bSizer56, 0, wxEXPAND, 5 );
|
||||
|
||||
m_panelMain->SetSizer( bSizer69 );
|
||||
m_panelMain->Layout();
|
||||
bSizer69->Fit( m_panelMain );
|
||||
@@ -486,12 +483,12 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w
|
||||
|
||||
// Connect Events
|
||||
m_listBox->Connect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( COptionsDialogBase::OnListBox ), NULL, this );
|
||||
m_textCtrlTransactionFee->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusTransactionFee ), NULL, this );
|
||||
m_checkBoxLimitProcessors->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxLimitProcessors ), NULL, this );
|
||||
m_checkBoxMinimizeToTray->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxMinimizeToTray ), NULL, this );
|
||||
m_checkBoxUseProxy->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxUseProxy ), NULL, this );
|
||||
m_textCtrlProxyIP->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusProxy ), NULL, this );
|
||||
m_textCtrlProxyPort->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusProxy ), NULL, this );
|
||||
m_textCtrlTransactionFee->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusTransactionFee ), NULL, this );
|
||||
m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonOK ), NULL, this );
|
||||
m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonCancel ), NULL, this );
|
||||
m_buttonApply->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonApply ), NULL, this );
|
||||
@@ -501,12 +498,12 @@ COptionsDialogBase::~COptionsDialogBase()
|
||||
{
|
||||
// Disconnect Events
|
||||
m_listBox->Disconnect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( COptionsDialogBase::OnListBox ), NULL, this );
|
||||
m_textCtrlTransactionFee->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusTransactionFee ), NULL, this );
|
||||
m_checkBoxLimitProcessors->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxLimitProcessors ), NULL, this );
|
||||
m_checkBoxMinimizeToTray->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxMinimizeToTray ), NULL, this );
|
||||
m_checkBoxUseProxy->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxUseProxy ), NULL, this );
|
||||
m_textCtrlProxyIP->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusProxy ), NULL, this );
|
||||
m_textCtrlProxyPort->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusProxy ), NULL, this );
|
||||
m_textCtrlTransactionFee->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusTransactionFee ), NULL, this );
|
||||
m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonOK ), NULL, this );
|
||||
m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonCancel ), NULL, this );
|
||||
m_buttonApply->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonApply ), NULL, this );
|
||||
|
||||
15
uibase.h
15
uibase.h
@@ -47,9 +47,9 @@
|
||||
#define wxID_TEXTCTRLADDRESS 1004
|
||||
#define wxID_BUTTONNEW 1005
|
||||
#define wxID_BUTTONCOPY 1006
|
||||
#define wxID_TRANSACTIONFEE 1007
|
||||
#define wxID_PROXYIP 1008
|
||||
#define wxID_PROXYPORT 1009
|
||||
#define wxID_PROXYIP 1007
|
||||
#define wxID_PROXYPORT 1008
|
||||
#define wxID_TRANSACTIONFEE 1009
|
||||
#define wxID_TEXTCTRLPAYTO 1010
|
||||
#define wxID_BUTTONPASTE 1011
|
||||
#define wxID_BUTTONADDRESSBOOK 1012
|
||||
@@ -163,9 +163,6 @@ class COptionsDialogBase : public wxDialog
|
||||
wxScrolledWindow* m_scrolledWindow;
|
||||
wxPanel* m_panelMain;
|
||||
|
||||
wxStaticText* m_staticText32;
|
||||
wxStaticText* m_staticText31;
|
||||
wxTextCtrl* m_textCtrlTransactionFee;
|
||||
wxCheckBox* m_checkBoxLimitProcessors;
|
||||
wxSpinCtrl* m_spinCtrlLimitProcessors;
|
||||
wxStaticText* m_staticText35;
|
||||
@@ -178,6 +175,10 @@ class COptionsDialogBase : public wxDialog
|
||||
wxTextCtrl* m_textCtrlProxyIP;
|
||||
wxStaticText* m_staticTextProxyPort;
|
||||
wxTextCtrl* m_textCtrlProxyPort;
|
||||
|
||||
wxStaticText* m_staticText32;
|
||||
wxStaticText* m_staticText31;
|
||||
wxTextCtrl* m_textCtrlTransactionFee;
|
||||
wxPanel* m_panelTest2;
|
||||
|
||||
wxStaticText* m_staticText321;
|
||||
@@ -188,11 +189,11 @@ class COptionsDialogBase : public wxDialog
|
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void OnListBox( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnKillFocusTransactionFee( wxFocusEvent& event ){ event.Skip(); }
|
||||
virtual void OnCheckBoxLimitProcessors( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnCheckBoxMinimizeToTray( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnCheckBoxUseProxy( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnKillFocusProxy( wxFocusEvent& event ){ event.Skip(); }
|
||||
virtual void OnKillFocusTransactionFee( wxFocusEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonOK( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnButtonApply( wxCommandEvent& event ){ event.Skip(); }
|
||||
|
||||
352
uiproject.fbp
352
uiproject.fbp
@@ -1488,7 +1488,7 @@
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="Dialog" expanded="0">
|
||||
<object class="Dialog" expanded="1">
|
||||
<property name="bg"></property>
|
||||
<property name="center"></property>
|
||||
<property name="context_help"></property>
|
||||
@@ -1540,7 +1540,7 @@
|
||||
<event name="OnSetFocus"></event>
|
||||
<event name="OnSize"></event>
|
||||
<event name="OnUpdateUI"></event>
|
||||
<object class="wxBoxSizer" expanded="0">
|
||||
<object class="wxBoxSizer" expanded="1">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bSizer55</property>
|
||||
<property name="orient">wxVERTICAL</property>
|
||||
@@ -1610,7 +1610,7 @@
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND|wxLEFT</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxScrolledWindow" expanded="0">
|
||||
<object class="wxScrolledWindow" expanded="1">
|
||||
<property name="bg"></property>
|
||||
<property name="context_help"></property>
|
||||
<property name="enabled">1</property>
|
||||
@@ -1720,174 +1720,6 @@
|
||||
<property name="width">0</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticText" expanded="1">
|
||||
<property name="bg"></property>
|
||||
<property name="context_help"></property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="font"></property>
|
||||
<property name="hidden">1</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Optional transaction fee you give to the nodes that process your transactions.</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">m_staticText32</property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pos"></property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass"></property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<property name="wrap">-1</property>
|
||||
<event name="OnChar"></event>
|
||||
<event name="OnEnterWindow"></event>
|
||||
<event name="OnEraseBackground"></event>
|
||||
<event name="OnKeyDown"></event>
|
||||
<event name="OnKeyUp"></event>
|
||||
<event name="OnKillFocus"></event>
|
||||
<event name="OnLeaveWindow"></event>
|
||||
<event name="OnLeftDClick"></event>
|
||||
<event name="OnLeftDown"></event>
|
||||
<event name="OnLeftUp"></event>
|
||||
<event name="OnMiddleDClick"></event>
|
||||
<event name="OnMiddleDown"></event>
|
||||
<event name="OnMiddleUp"></event>
|
||||
<event name="OnMotion"></event>
|
||||
<event name="OnMouseEvents"></event>
|
||||
<event name="OnMouseWheel"></event>
|
||||
<event name="OnPaint"></event>
|
||||
<event name="OnRightDClick"></event>
|
||||
<event name="OnRightDown"></event>
|
||||
<event name="OnRightUp"></event>
|
||||
<event name="OnSetFocus"></event>
|
||||
<event name="OnSize"></event>
|
||||
<event name="OnUpdateUI"></event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxBoxSizer" expanded="1">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bSizer56</property>
|
||||
<property name="orient">wxHORIZONTAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticText" expanded="1">
|
||||
<property name="bg"></property>
|
||||
<property name="context_help"></property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="font"></property>
|
||||
<property name="hidden">1</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Transaction fee:</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">m_staticText31</property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pos"></property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass"></property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<property name="wrap">-1</property>
|
||||
<event name="OnChar"></event>
|
||||
<event name="OnEnterWindow"></event>
|
||||
<event name="OnEraseBackground"></event>
|
||||
<event name="OnKeyDown"></event>
|
||||
<event name="OnKeyUp"></event>
|
||||
<event name="OnKillFocus"></event>
|
||||
<event name="OnLeaveWindow"></event>
|
||||
<event name="OnLeftDClick"></event>
|
||||
<event name="OnLeftDown"></event>
|
||||
<event name="OnLeftUp"></event>
|
||||
<event name="OnMiddleDClick"></event>
|
||||
<event name="OnMiddleDown"></event>
|
||||
<event name="OnMiddleUp"></event>
|
||||
<event name="OnMotion"></event>
|
||||
<event name="OnMouseEvents"></event>
|
||||
<event name="OnMouseWheel"></event>
|
||||
<event name="OnPaint"></event>
|
||||
<event name="OnRightDClick"></event>
|
||||
<event name="OnRightDown"></event>
|
||||
<event name="OnRightUp"></event>
|
||||
<event name="OnSetFocus"></event>
|
||||
<event name="OnSize"></event>
|
||||
<event name="OnUpdateUI"></event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxTextCtrl" expanded="1">
|
||||
<property name="bg"></property>
|
||||
<property name="context_help"></property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="font"></property>
|
||||
<property name="hidden">1</property>
|
||||
<property name="id">wxID_TRANSACTIONFEE</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="maxlength">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">m_textCtrlTransactionFee</property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pos"></property>
|
||||
<property name="size">70,-1</property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass"></property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="value"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnChar"></event>
|
||||
<event name="OnEnterWindow"></event>
|
||||
<event name="OnEraseBackground"></event>
|
||||
<event name="OnKeyDown"></event>
|
||||
<event name="OnKeyUp"></event>
|
||||
<event name="OnKillFocus">OnKillFocusTransactionFee</event>
|
||||
<event name="OnLeaveWindow"></event>
|
||||
<event name="OnLeftDClick"></event>
|
||||
<event name="OnLeftDown"></event>
|
||||
<event name="OnLeftUp"></event>
|
||||
<event name="OnMiddleDClick"></event>
|
||||
<event name="OnMiddleDown"></event>
|
||||
<event name="OnMiddleUp"></event>
|
||||
<event name="OnMotion"></event>
|
||||
<event name="OnMouseEvents"></event>
|
||||
<event name="OnMouseWheel"></event>
|
||||
<event name="OnPaint"></event>
|
||||
<event name="OnRightDClick"></event>
|
||||
<event name="OnRightDown"></event>
|
||||
<event name="OnRightUp"></event>
|
||||
<event name="OnSetFocus"></event>
|
||||
<event name="OnSize"></event>
|
||||
<event name="OnText"></event>
|
||||
<event name="OnTextEnter"></event>
|
||||
<event name="OnTextMaxLen"></event>
|
||||
<event name="OnTextURL"></event>
|
||||
<event name="OnUpdateUI"></event>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag"></property>
|
||||
@@ -2509,6 +2341,184 @@
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag"></property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="spacer" expanded="1">
|
||||
<property name="height">1</property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="width">0</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticText" expanded="1">
|
||||
<property name="bg"></property>
|
||||
<property name="context_help"></property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="font"></property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended.</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">m_staticText32</property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pos"></property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass"></property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<property name="wrap">365</property>
|
||||
<event name="OnChar"></event>
|
||||
<event name="OnEnterWindow"></event>
|
||||
<event name="OnEraseBackground"></event>
|
||||
<event name="OnKeyDown"></event>
|
||||
<event name="OnKeyUp"></event>
|
||||
<event name="OnKillFocus"></event>
|
||||
<event name="OnLeaveWindow"></event>
|
||||
<event name="OnLeftDClick"></event>
|
||||
<event name="OnLeftDown"></event>
|
||||
<event name="OnLeftUp"></event>
|
||||
<event name="OnMiddleDClick"></event>
|
||||
<event name="OnMiddleDown"></event>
|
||||
<event name="OnMiddleUp"></event>
|
||||
<event name="OnMotion"></event>
|
||||
<event name="OnMouseEvents"></event>
|
||||
<event name="OnMouseWheel"></event>
|
||||
<event name="OnPaint"></event>
|
||||
<event name="OnRightDClick"></event>
|
||||
<event name="OnRightDown"></event>
|
||||
<event name="OnRightUp"></event>
|
||||
<event name="OnSetFocus"></event>
|
||||
<event name="OnSize"></event>
|
||||
<event name="OnUpdateUI"></event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxBoxSizer" expanded="1">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bSizer56</property>
|
||||
<property name="orient">wxHORIZONTAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticText" expanded="1">
|
||||
<property name="bg"></property>
|
||||
<property name="context_help"></property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="font"></property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Pay transaction fee:</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">m_staticText31</property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pos"></property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass"></property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<property name="wrap">-1</property>
|
||||
<event name="OnChar"></event>
|
||||
<event name="OnEnterWindow"></event>
|
||||
<event name="OnEraseBackground"></event>
|
||||
<event name="OnKeyDown"></event>
|
||||
<event name="OnKeyUp"></event>
|
||||
<event name="OnKillFocus"></event>
|
||||
<event name="OnLeaveWindow"></event>
|
||||
<event name="OnLeftDClick"></event>
|
||||
<event name="OnLeftDown"></event>
|
||||
<event name="OnLeftUp"></event>
|
||||
<event name="OnMiddleDClick"></event>
|
||||
<event name="OnMiddleDown"></event>
|
||||
<event name="OnMiddleUp"></event>
|
||||
<event name="OnMotion"></event>
|
||||
<event name="OnMouseEvents"></event>
|
||||
<event name="OnMouseWheel"></event>
|
||||
<event name="OnPaint"></event>
|
||||
<event name="OnRightDClick"></event>
|
||||
<event name="OnRightDown"></event>
|
||||
<event name="OnRightUp"></event>
|
||||
<event name="OnSetFocus"></event>
|
||||
<event name="OnSize"></event>
|
||||
<event name="OnUpdateUI"></event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxTextCtrl" expanded="1">
|
||||
<property name="bg"></property>
|
||||
<property name="context_help"></property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="font"></property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_TRANSACTIONFEE</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="maxlength">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">m_textCtrlTransactionFee</property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pos"></property>
|
||||
<property name="size">70,-1</property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass"></property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="value"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnChar"></event>
|
||||
<event name="OnEnterWindow"></event>
|
||||
<event name="OnEraseBackground"></event>
|
||||
<event name="OnKeyDown"></event>
|
||||
<event name="OnKeyUp"></event>
|
||||
<event name="OnKillFocus">OnKillFocusTransactionFee</event>
|
||||
<event name="OnLeaveWindow"></event>
|
||||
<event name="OnLeftDClick"></event>
|
||||
<event name="OnLeftDown"></event>
|
||||
<event name="OnLeftUp"></event>
|
||||
<event name="OnMiddleDClick"></event>
|
||||
<event name="OnMiddleDown"></event>
|
||||
<event name="OnMiddleUp"></event>
|
||||
<event name="OnMotion"></event>
|
||||
<event name="OnMouseEvents"></event>
|
||||
<event name="OnMouseWheel"></event>
|
||||
<event name="OnPaint"></event>
|
||||
<event name="OnRightDClick"></event>
|
||||
<event name="OnRightDown"></event>
|
||||
<event name="OnRightUp"></event>
|
||||
<event name="OnSetFocus"></event>
|
||||
<event name="OnSize"></event>
|
||||
<event name="OnText"></event>
|
||||
<event name="OnTextEnter"></event>
|
||||
<event name="OnTextMaxLen"></event>
|
||||
<event name="OnTextURL"></event>
|
||||
<event name="OnUpdateUI"></event>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
136
util.cpp
136
util.cpp
@@ -11,10 +11,12 @@ bool fDebug = false;
|
||||
bool fPrintToConsole = false;
|
||||
bool fPrintToDebugger = false;
|
||||
char pszSetDataDir[MAX_PATH] = "";
|
||||
bool fRequestShutdown = false;
|
||||
bool fShutdown = false;
|
||||
bool fDaemon = false;
|
||||
bool fCommandLine = false;
|
||||
string strMiscWarning;
|
||||
bool fTestNet = false;
|
||||
|
||||
|
||||
|
||||
@@ -79,7 +81,7 @@ instance_of_cinit;
|
||||
void RandAddSeed()
|
||||
{
|
||||
// Seed with CPU performance counter
|
||||
int64 nCounter = PerformanceCounter();
|
||||
int64 nCounter = GetPerformanceCounter();
|
||||
RAND_add(&nCounter, sizeof(nCounter), 1.5);
|
||||
memset(&nCounter, 0, sizeof(nCounter));
|
||||
}
|
||||
@@ -126,6 +128,11 @@ uint64 GetRand(uint64 nMax)
|
||||
return (nRand % nMax);
|
||||
}
|
||||
|
||||
int GetRandInt(int nMax)
|
||||
{
|
||||
return GetRand(nMax);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -150,10 +157,16 @@ inline int OutputDebugStringF(const char* pszFormat, ...)
|
||||
else
|
||||
{
|
||||
// print to debug.log
|
||||
char pszFile[MAX_PATH+100];
|
||||
GetDataDir(pszFile);
|
||||
strlcat(pszFile, "/debug.log", sizeof(pszFile));
|
||||
FILE* fileout = fopen(pszFile, "a");
|
||||
static FILE* fileout = NULL;
|
||||
|
||||
if (!fileout)
|
||||
{
|
||||
char pszFile[MAX_PATH+100];
|
||||
GetDataDir(pszFile);
|
||||
strlcat(pszFile, "/debug.log", sizeof(pszFile));
|
||||
fileout = fopen(pszFile, "a");
|
||||
setbuf(fileout, NULL); // unbuffered
|
||||
}
|
||||
if (fileout)
|
||||
{
|
||||
//// Debug print useful for profiling
|
||||
@@ -162,15 +175,15 @@ inline int OutputDebugStringF(const char* pszFormat, ...)
|
||||
va_start(arg_ptr, pszFormat);
|
||||
ret = vfprintf(fileout, pszFormat, arg_ptr);
|
||||
va_end(arg_ptr);
|
||||
fclose(fileout);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __WXMSW__
|
||||
if (fPrintToDebugger)
|
||||
{
|
||||
// accumulate a line at a time
|
||||
static CCriticalSection cs_OutputDebugStringF;
|
||||
|
||||
// accumulate a line at a time
|
||||
CRITICAL_BLOCK(cs_OutputDebugStringF)
|
||||
{
|
||||
static char pszBuffer[50000];
|
||||
@@ -392,11 +405,11 @@ vector<unsigned char> ParseHex(const char* psz)
|
||||
while (isspace(*psz))
|
||||
psz++;
|
||||
char c = phexdigit[(unsigned char)*psz++];
|
||||
if (c == -1)
|
||||
if (c == (char)-1)
|
||||
break;
|
||||
unsigned char n = (c << 4);
|
||||
c = phexdigit[(unsigned char)*psz++];
|
||||
if (c == -1)
|
||||
if (c == (char)-1)
|
||||
break;
|
||||
n |= c;
|
||||
vch.push_back(n);
|
||||
@@ -404,7 +417,7 @@ vector<unsigned char> ParseHex(const char* psz)
|
||||
return vch;
|
||||
}
|
||||
|
||||
vector<unsigned char> ParseHex(const std::string& str)
|
||||
vector<unsigned char> ParseHex(const string& str)
|
||||
{
|
||||
return ParseHex(str.c_str());
|
||||
}
|
||||
@@ -472,6 +485,34 @@ const char* wxGetTranslation(const char* pszEnglish)
|
||||
}
|
||||
|
||||
|
||||
bool WildcardMatch(const char* psz, const char* mask)
|
||||
{
|
||||
loop
|
||||
{
|
||||
switch (*mask)
|
||||
{
|
||||
case '\0':
|
||||
return (*psz == '\0');
|
||||
case '*':
|
||||
return WildcardMatch(psz, mask+1) || (*psz && WildcardMatch(psz+1, mask));
|
||||
case '?':
|
||||
if (*psz == '\0')
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
if (*psz != *mask)
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
psz++;
|
||||
mask++;
|
||||
}
|
||||
}
|
||||
|
||||
bool WildcardMatch(const string& str, const string& mask)
|
||||
{
|
||||
return WildcardMatch(str.c_str(), mask.c_str());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -499,23 +540,47 @@ void FormatException(char* pszMessage, std::exception* pex, const char* pszThrea
|
||||
|
||||
void LogException(std::exception* pex, const char* pszThread)
|
||||
{
|
||||
char pszMessage[1000];
|
||||
char pszMessage[10000];
|
||||
FormatException(pszMessage, pex, pszThread);
|
||||
printf("\n%s", pszMessage);
|
||||
}
|
||||
|
||||
void PrintException(std::exception* pex, const char* pszThread)
|
||||
{
|
||||
char pszMessage[1000];
|
||||
char pszMessage[10000];
|
||||
FormatException(pszMessage, pex, pszThread);
|
||||
printf("\n\n************************\n%s\n", pszMessage);
|
||||
fprintf(stderr, "\n\n************************\n%s\n", pszMessage);
|
||||
strMiscWarning = pszMessage;
|
||||
#ifdef GUI
|
||||
if (wxTheApp && !fDaemon)
|
||||
MyMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR);
|
||||
MyMessageBox(pszMessage, "Bitcoin", wxOK | wxICON_ERROR);
|
||||
#endif
|
||||
throw;
|
||||
//DebugBreak();
|
||||
}
|
||||
|
||||
void ThreadOneMessageBox(string strMessage)
|
||||
{
|
||||
// Skip message boxes if one is already open
|
||||
static bool fMessageBoxOpen;
|
||||
if (fMessageBoxOpen)
|
||||
return;
|
||||
fMessageBoxOpen = true;
|
||||
ThreadSafeMessageBox(strMessage, "Bitcoin", wxOK | wxICON_EXCLAMATION);
|
||||
fMessageBoxOpen = false;
|
||||
}
|
||||
|
||||
void PrintExceptionContinue(std::exception* pex, const char* pszThread)
|
||||
{
|
||||
char pszMessage[10000];
|
||||
FormatException(pszMessage, pex, pszThread);
|
||||
printf("\n\n************************\n%s\n", pszMessage);
|
||||
fprintf(stderr, "\n\n************************\n%s\n", pszMessage);
|
||||
strMiscWarning = pszMessage;
|
||||
#ifdef GUI
|
||||
if (wxTheApp && !fDaemon)
|
||||
boost::thread(boost::bind(ThreadOneMessageBox, string(pszMessage)));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -591,15 +656,11 @@ string GetDefaultDataDir()
|
||||
void GetDataDir(char* pszDir)
|
||||
{
|
||||
// pszDir must be at least MAX_PATH length.
|
||||
int nVariation;
|
||||
if (pszSetDataDir[0] != 0)
|
||||
{
|
||||
strlcpy(pszDir, pszSetDataDir, MAX_PATH);
|
||||
static bool fMkdirDone;
|
||||
if (!fMkdirDone)
|
||||
{
|
||||
fMkdirDone = true;
|
||||
filesystem::create_directory(pszDir);
|
||||
}
|
||||
nVariation = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -607,11 +668,23 @@ void GetDataDir(char* pszDir)
|
||||
// value so we don't have to do memory allocations after that.
|
||||
static char pszCachedDir[MAX_PATH];
|
||||
if (pszCachedDir[0] == 0)
|
||||
{
|
||||
strlcpy(pszCachedDir, GetDefaultDataDir().c_str(), sizeof(pszCachedDir));
|
||||
filesystem::create_directory(pszCachedDir);
|
||||
}
|
||||
strlcpy(pszDir, pszCachedDir, MAX_PATH);
|
||||
nVariation = 1;
|
||||
}
|
||||
if (fTestNet)
|
||||
{
|
||||
char* p = pszDir + strlen(pszDir);
|
||||
if (p > pszDir && p[-1] != '/' && p[-1] != '\\')
|
||||
*p++ = '/';
|
||||
strcpy(p, "testnet");
|
||||
nVariation += 2;
|
||||
}
|
||||
static bool pfMkdir[4];
|
||||
if (!pfMkdir[nVariation])
|
||||
{
|
||||
pfMkdir[nVariation] = true;
|
||||
filesystem::create_directory(pszDir);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -625,7 +698,7 @@ string GetDataDir()
|
||||
string GetConfigFile()
|
||||
{
|
||||
namespace fs = boost::filesystem;
|
||||
fs::path pathConfig(mapArgs.count("-conf") ? mapArgs["-conf"] : string("bitcoin.conf"));
|
||||
fs::path pathConfig(GetArg("-conf", "bitcoin.conf"));
|
||||
if (!pathConfig.is_complete())
|
||||
pathConfig = fs::path(GetDataDir()) / pathConfig;
|
||||
return pathConfig.string();
|
||||
@@ -693,13 +766,10 @@ void ShrinkDebugFile()
|
||||
|
||||
//
|
||||
// "Never go to sea with two chronometers; take one or three."
|
||||
// Our three chronometers are:
|
||||
// Our three time sources are:
|
||||
// - System clock
|
||||
// - Median of other server's clocks
|
||||
// - NTP servers
|
||||
//
|
||||
// note: NTP isn't implemented yet, so until then we just use the median
|
||||
// of other nodes clocks to correct ours.
|
||||
// - Median of other nodes's clocks
|
||||
// - The user (asking the user to fix the system clock if the first two disagree)
|
||||
//
|
||||
int64 GetTime()
|
||||
{
|
||||
@@ -743,16 +813,16 @@ void AddTimeData(unsigned int ip, int64 nTime)
|
||||
// If nobody else has the same time as us, give a warning
|
||||
bool fMatch = false;
|
||||
foreach(int64 nOffset, vTimeOffsets)
|
||||
if (nOffset != 0 && abs64(nOffset) < 10 * 60)
|
||||
if (nOffset != 0 && abs64(nOffset) < 5 * 60)
|
||||
fMatch = true;
|
||||
static bool fDone;
|
||||
if (!fMatch && !fDone)
|
||||
{
|
||||
fDone = true;
|
||||
string strMessage = _("Warning: Check your system date and time, you may not be able to generate or receive the most recent blocks!");
|
||||
string strMessage = _("Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly.");
|
||||
strMiscWarning = strMessage;
|
||||
printf("*** %s\n", strMessage.c_str());
|
||||
boost::thread(bind(ThreadSafeMessageBox, strMessage+" ", string("Bitcoin"), wxOK | wxICON_EXCLAMATION, (wxWindow*)NULL, -1, -1));
|
||||
boost::thread(boost::bind(ThreadSafeMessageBox, strMessage+" ", string("Bitcoin"), wxOK | wxICON_EXCLAMATION, (wxWindow*)NULL, -1, -1));
|
||||
}
|
||||
}
|
||||
foreach(int64 n, vTimeOffsets)
|
||||
|
||||
104
util.h
104
util.h
@@ -140,10 +140,12 @@ extern bool fDebug;
|
||||
extern bool fPrintToConsole;
|
||||
extern bool fPrintToDebugger;
|
||||
extern char pszSetDataDir[MAX_PATH];
|
||||
extern bool fRequestShutdown;
|
||||
extern bool fShutdown;
|
||||
extern bool fDaemon;
|
||||
extern bool fCommandLine;
|
||||
extern string strMiscWarning;
|
||||
extern bool fTestNet;
|
||||
|
||||
void RandAddSeed();
|
||||
void RandAddSeedPerfmon();
|
||||
@@ -151,16 +153,19 @@ int OutputDebugStringF(const char* pszFormat, ...);
|
||||
int my_snprintf(char* buffer, size_t limit, const char* format, ...);
|
||||
string strprintf(const char* format, ...);
|
||||
bool error(const char* format, ...);
|
||||
void PrintException(std::exception* pex, const char* pszThread);
|
||||
void LogException(std::exception* pex, const char* pszThread);
|
||||
void PrintException(std::exception* pex, const char* pszThread);
|
||||
void PrintExceptionContinue(std::exception* pex, const char* pszThread);
|
||||
void ParseString(const string& str, char c, vector<string>& v);
|
||||
string FormatMoney(int64 n, bool fPlus=false);
|
||||
bool ParseMoney(const string& str, int64& nRet);
|
||||
bool ParseMoney(const char* pszIn, int64& nRet);
|
||||
vector<unsigned char> ParseHex(const char* psz);
|
||||
vector<unsigned char> ParseHex(const std::string& str);
|
||||
vector<unsigned char> ParseHex(const string& str);
|
||||
void ParseParameters(int argc, char* argv[]);
|
||||
const char* wxGetTranslation(const char* psz);
|
||||
bool WildcardMatch(const char* psz, const char* mask);
|
||||
bool WildcardMatch(const string& str, const string& mask);
|
||||
int GetFilesize(FILE* file);
|
||||
void GetDataDir(char* pszDirRet);
|
||||
string GetConfigFile();
|
||||
@@ -171,6 +176,7 @@ string MyGetSpecialFolderPath(int nFolder, bool fCreate);
|
||||
string GetDefaultDataDir();
|
||||
string GetDataDir();
|
||||
void ShrinkDebugFile();
|
||||
int GetRandInt(int nMax);
|
||||
uint64 GetRand(uint64 nMax);
|
||||
int64 GetTime();
|
||||
int64 GetAdjustedTime();
|
||||
@@ -305,19 +311,20 @@ inline int64 abs64(int64 n)
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
string HexStr(const T itbegin, const T itend, bool fSpaces=true)
|
||||
string HexStr(const T itbegin, const T itend, bool fSpaces=false)
|
||||
{
|
||||
if (itbegin == itend)
|
||||
return "";
|
||||
const unsigned char* pbegin = (const unsigned char*)&itbegin[0];
|
||||
const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]);
|
||||
string str;
|
||||
str.reserve((pend-pbegin) * (fSpaces ? 3 : 2));
|
||||
for (const unsigned char* p = pbegin; p != pend; p++)
|
||||
str += strprintf((fSpaces && p != pend-1 ? "%02x " : "%02x"), *p);
|
||||
return str;
|
||||
}
|
||||
|
||||
inline string HexStr(vector<unsigned char> vch, bool fSpaces=true)
|
||||
inline string HexStr(const vector<unsigned char>& vch, bool fSpaces=false)
|
||||
{
|
||||
return HexStr(vch.begin(), vch.end(), fSpaces);
|
||||
}
|
||||
@@ -330,23 +337,29 @@ string HexNumStr(const T itbegin, const T itend, bool f0x=true)
|
||||
const unsigned char* pbegin = (const unsigned char*)&itbegin[0];
|
||||
const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]);
|
||||
string str = (f0x ? "0x" : "");
|
||||
str.reserve(str.size() + (pend-pbegin) * 2);
|
||||
for (const unsigned char* p = pend-1; p >= pbegin; p--)
|
||||
str += strprintf("%02X", *p);
|
||||
str += strprintf("%02x", *p);
|
||||
return str;
|
||||
}
|
||||
|
||||
inline string HexNumStr(const vector<unsigned char>& vch, bool f0x=true)
|
||||
{
|
||||
return HexNumStr(vch.begin(), vch.end(), f0x);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void PrintHex(const T pbegin, const T pend, const char* pszFormat="%s", bool fSpaces=true)
|
||||
{
|
||||
printf(pszFormat, HexStr(pbegin, pend, fSpaces).c_str());
|
||||
}
|
||||
|
||||
inline void PrintHex(vector<unsigned char> vch, const char* pszFormat="%s", bool fSpaces=true)
|
||||
inline void PrintHex(const vector<unsigned char>& vch, const char* pszFormat="%s", bool fSpaces=true)
|
||||
{
|
||||
printf(pszFormat, HexStr(vch, fSpaces).c_str());
|
||||
}
|
||||
|
||||
inline int64 PerformanceCounter()
|
||||
inline int64 GetPerformanceCounter()
|
||||
{
|
||||
int64 nCounter = 0;
|
||||
#ifdef __WXMSW__
|
||||
@@ -390,6 +403,39 @@ inline bool IsSwitchChar(char c)
|
||||
#endif
|
||||
}
|
||||
|
||||
inline string GetArg(const string& strArg, const string& strDefault)
|
||||
{
|
||||
if (mapArgs.count(strArg))
|
||||
return mapArgs[strArg];
|
||||
return strDefault;
|
||||
}
|
||||
|
||||
inline int64 GetArg(const string& strArg, int64 nDefault)
|
||||
{
|
||||
if (mapArgs.count(strArg))
|
||||
return atoi64(mapArgs[strArg]);
|
||||
return nDefault;
|
||||
}
|
||||
|
||||
inline bool GetBoolArg(const string& strArg)
|
||||
{
|
||||
if (mapArgs.count(strArg))
|
||||
{
|
||||
if (mapArgs[strArg].empty())
|
||||
return true;
|
||||
return (atoi(mapArgs[strArg]) != 0);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline string FormatVersion(int nVersion)
|
||||
{
|
||||
if (nVersion%100 == 0)
|
||||
return strprintf("%d.%d.%d", nVersion/1000000, (nVersion/10000)%100, (nVersion/100)%100);
|
||||
else
|
||||
return strprintf("%d.%d.%d.%d", nVersion/1000000, (nVersion/10000)%100, (nVersion/100)%100, nVersion%100);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -409,16 +455,16 @@ inline void heapchk()
|
||||
}
|
||||
|
||||
// Randomize the stack to help protect against buffer overrun exploits
|
||||
#define IMPLEMENT_RANDOMIZE_STACK(ThreadFn) \
|
||||
{ \
|
||||
static char nLoops; \
|
||||
if (nLoops <= 0) \
|
||||
nLoops = GetRand(20) + 1; \
|
||||
if (nLoops-- > 1) \
|
||||
{ \
|
||||
ThreadFn; \
|
||||
return; \
|
||||
} \
|
||||
#define IMPLEMENT_RANDOMIZE_STACK(ThreadFn) \
|
||||
{ \
|
||||
static char nLoops; \
|
||||
if (nLoops <= 0) \
|
||||
nLoops = GetRand(20) + 1; \
|
||||
if (nLoops-- > 1) \
|
||||
{ \
|
||||
ThreadFn; \
|
||||
return; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CATCH_PRINT_EXCEPTION(pszFn) \
|
||||
@@ -587,3 +633,27 @@ inline void ExitThread(unsigned int nExitCode)
|
||||
pthread_exit((void*)nExitCode);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
inline bool AffinityBugWorkaround(void(*pfn)(void*))
|
||||
{
|
||||
#ifdef __WXMSW__
|
||||
// Sometimes after a few hours affinity gets stuck on one processor
|
||||
DWORD dwProcessAffinityMask = -1;
|
||||
DWORD dwSystemAffinityMask = -1;
|
||||
GetProcessAffinityMask(GetCurrentProcess(), &dwProcessAffinityMask, &dwSystemAffinityMask);
|
||||
DWORD dwPrev1 = SetThreadAffinityMask(GetCurrentThread(), dwProcessAffinityMask);
|
||||
DWORD dwPrev2 = SetThreadAffinityMask(GetCurrentThread(), dwProcessAffinityMask);
|
||||
if (dwPrev2 != dwProcessAffinityMask)
|
||||
{
|
||||
printf("AffinityBugWorkaround() : SetThreadAffinityMask=%d, ProcessAffinityMask=%d, restarting thread\n", dwPrev2, dwProcessAffinityMask);
|
||||
if (!CreateThread(pfn, NULL))
|
||||
printf("Error: CreateThread() failed\n");
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user