diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/addrman.cpp | 4 | ||||
-rw-r--r-- | src/addrman.h | 2 | ||||
-rw-r--r-- | src/base58.h | 2 | ||||
-rw-r--r-- | src/bitcoinrpc.cpp | 2 | ||||
-rw-r--r-- | src/clientversion.h | 2 | ||||
-rw-r--r-- | src/db.cpp | 4 | ||||
-rw-r--r-- | src/key.h | 2 | ||||
-rw-r--r-- | src/main.cpp | 56 | ||||
-rw-r--r-- | src/main.h | 50 | ||||
-rw-r--r-- | src/makefile.linux-mingw | 2 | ||||
-rw-r--r-- | src/makefile.mingw | 6 | ||||
-rw-r--r-- | src/makefile.osx | 5 | ||||
-rw-r--r-- | src/makefile.unix | 5 | ||||
-rw-r--r-- | src/netbase.cpp | 8 | ||||
-rw-r--r-- | src/qt/bitcoingui.cpp | 101 | ||||
-rw-r--r-- | src/qt/bitcoingui.h | 1 | ||||
-rw-r--r-- | src/qt/rpcconsole.cpp | 32 | ||||
-rw-r--r-- | src/qt/transactionrecord.cpp | 14 | ||||
-rw-r--r-- | src/rpcnet.cpp | 2 | ||||
-rw-r--r-- | src/rpcwallet.cpp | 4 | ||||
-rw-r--r-- | src/sync.cpp | 2 | ||||
-rw-r--r-- | src/test/accounting_tests.cpp | 2 | ||||
-rw-r--r-- | src/test/data/tx_invalid.json | 40 | ||||
-rw-r--r-- | src/test/data/tx_valid.json | 21 | ||||
-rw-r--r-- | src/test/transaction_tests.cpp | 10 | ||||
-rw-r--r-- | src/util.h | 4 | ||||
-rw-r--r-- | src/wallet.cpp | 11 | ||||
-rw-r--r-- | src/wallet.h | 9 | ||||
-rw-r--r-- | src/walletdb.cpp | 4 | ||||
-rw-r--r-- | src/walletdb.h | 6 |
30 files changed, 238 insertions, 175 deletions
diff --git a/src/addrman.cpp b/src/addrman.cpp index 321ebd1e2b..4428cd169a 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -187,7 +187,7 @@ int CAddrMan::ShrinkNew(int nUBucket) } assert(mapInfo.count(nOldest) == 1); CAddrInfo &info = mapInfo[nOldest]; - if (--info.nRefCount == 0) + if (--info.nRefCount == 0) { SwapRandom(info.nRandomPos, vRandom.size()-1); vRandom.pop_back(); @@ -241,7 +241,7 @@ void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin) infoOld.nRefCount = 1; // do not update nTried, as we are going to move something else there immediately - // check whether there is place in that one, + // check whether there is place in that one, if (vNew.size() < ADDRMAN_NEW_BUCKET_SIZE) { // if so, move it back there diff --git a/src/addrman.h b/src/addrman.h index 7c141c427b..7af6afd78f 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -214,7 +214,7 @@ protected: // This is the only place where actual deletes occur. // They are never deleted while in the "tried" table, only possibly evicted back to the "new" table. int ShrinkNew(int nUBucket); - + // Move an entry from the "new" table(s) to the "tried" table // @pre vvUnkown[nOrigin].count(nId) != 0 void MakeTried(CAddrInfo& info, int nId, int nOrigin); diff --git a/src/base58.h b/src/base58.h index fc8c8aa5de..9dfea86ff5 100644 --- a/src/base58.h +++ b/src/base58.h @@ -403,7 +403,7 @@ class CBitcoinSecret : public CBase58Data { public: void SetSecret(const CSecret& vchSecret, bool fCompressed) - { + { assert(vchSecret.size() == 32); SetData(fTestNet ? 239 : 128, &vchSecret[0], vchSecret.size()); if (fCompressed) diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 64154bf1b7..c3c2db38a2 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -983,7 +983,7 @@ void ThreadRPCServer3(void* parg) strReply = JSONRPCExecBatch(valRequest.get_array()); else throw JSONRPCError(-32700, "Top-level object parse error"); - + conn->stream() << HTTPReply(200, strReply, fRun) << std::flush; } catch (Object& objError) diff --git a/src/clientversion.h b/src/clientversion.h index c9d1a7b29c..548105383c 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -9,7 +9,7 @@ #define CLIENT_VERSION_MAJOR 0 #define CLIENT_VERSION_MINOR 7 #define CLIENT_VERSION_REVISION 0 -#define CLIENT_VERSION_BUILD 3 +#define CLIENT_VERSION_BUILD 99 // Converts the parameter X to a string after macro replacement on X has been performed. // Don't merge these into one macro! diff --git a/src/db.cpp b/src/db.cpp index 015e7ec2de..867703fbd2 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -281,7 +281,7 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip) { // surround usage of db with extra {} CDB db(strFile.c_str(), "r"); Db* pdbCopy = new Db(&bitdb.dbenv, 0); - + int ret = pdbCopy->open(NULL, // Txn pointer strFileRes.c_str(), // Filename "main", // Logical db name @@ -293,7 +293,7 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip) printf("Cannot create database file %s\n", strFileRes.c_str()); fSuccess = false; } - + Dbc* pcursor = db.GetCursor(); if (pcursor) while (fSuccess) @@ -99,7 +99,7 @@ public: }; -// secure_allocator is defined in serialize.h +// secure_allocator is defined in allocators.h // CPrivKey is a serialized private key, with all parameters included (279 bytes) typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey; // CSecret is a serialization of just the secret parameter (32 bytes) diff --git a/src/main.cpp b/src/main.cpp index 9b43825433..fbaf05dfc7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -477,6 +477,55 @@ bool CTransaction::CheckTransaction() const return true; } +int64 CTransaction::GetMinFee(unsigned int nBlockSize, bool fAllowFree, + enum GetMinFee_mode mode) const +{ + // Base fee is either MIN_TX_FEE or MIN_RELAY_TX_FEE + int64 nBaseFee = (mode == GMF_RELAY) ? MIN_RELAY_TX_FEE : MIN_TX_FEE; + + unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION); + unsigned int nNewBlockSize = nBlockSize + nBytes; + int64 nMinFee = (1 + (int64)nBytes / 1000) * nBaseFee; + + if (fAllowFree) + { + if (nBlockSize == 1) + { + // Transactions under 10K are free + // (about 4500 BTC if made of 50 BTC inputs) + if (nBytes < 10000) + nMinFee = 0; + } + else + { + // Free transaction area + if (nNewBlockSize < 27000) + nMinFee = 0; + } + } + + // To limit dust spam, require MIN_TX_FEE/MIN_RELAY_TX_FEE if any output is less than 0.01 + if (nMinFee < nBaseFee) + { + BOOST_FOREACH(const CTxOut& txout, vout) + if (txout.nValue < CENT) + nMinFee = nBaseFee; + } + + // 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 CTxMemPool::accept(CTxDB& txdb, CTransaction &tx, bool fCheckInputs, bool* pfMissingInputs) { @@ -563,8 +612,11 @@ bool CTxMemPool::accept(CTxDB& txdb, CTransaction &tx, bool fCheckInputs, unsigned int nSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); // Don't accept it if it can't get into a block - if (nFees < tx.GetMinFee(1000, true, GMF_RELAY)) - return error("CTxMemPool::accept() : not enough fees"); + int64 txMinFee = tx.GetMinFee(1000, true, GMF_RELAY); + if (nFees < txMinFee) + return error("CTxMemPool::accept() : not enough fees %s, %"PRI64d" < %"PRI64d, + hash.ToString().c_str(), + nFees, txMinFee); // Continuously rate-limit free transactions // This mitigates 'penny-flooding' -- sending thousands of free transactions just to diff --git a/src/main.h b/src/main.h index a233f00f46..770c202338 100644 --- a/src/main.h +++ b/src/main.h @@ -540,53 +540,7 @@ public: return dPriority > COIN * 144 / 250; } - int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=true, enum GetMinFee_mode mode=GMF_BLOCK) const - { - // Base fee is either MIN_TX_FEE or MIN_RELAY_TX_FEE - int64 nBaseFee = (mode == GMF_RELAY) ? MIN_RELAY_TX_FEE : MIN_TX_FEE; - - unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION); - unsigned int nNewBlockSize = nBlockSize + nBytes; - int64 nMinFee = (1 + (int64)nBytes / 1000) * nBaseFee; - - if (fAllowFree) - { - if (nBlockSize == 1) - { - // Transactions under 10K are free - // (about 4500 BTC if made of 50 BTC inputs) - if (nBytes < 10000) - nMinFee = 0; - } - else - { - // Free transaction area - if (nNewBlockSize < 27000) - nMinFee = 0; - } - } - - // To limit dust spam, require MIN_TX_FEE/MIN_RELAY_TX_FEE if any output is less than 0.01 - if (nMinFee < nBaseFee) - { - BOOST_FOREACH(const CTxOut& txout, vout) - if (txout.nValue < CENT) - nMinFee = nBaseFee; - } - - // 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; - } - + int64 GetMinFee(unsigned int nBlockSize=1, bool fAllowFree=true, enum GetMinFee_mode mode=GMF_BLOCK) const; bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL) { @@ -799,7 +753,7 @@ public: return !(a == b); } int GetDepthInMainChain() const; - + }; diff --git a/src/makefile.linux-mingw b/src/makefile.linux-mingw index 4ba0cf06f0..2804f14055 100644 --- a/src/makefile.linux-mingw +++ b/src/makefile.linux-mingw @@ -111,6 +111,6 @@ clean: -rm -f bitcoind.exe -rm -f obj-test/*.o -rm -f test_bitcoin.exe - -rm -f src/build.h + -rm -f obj/build.h FORCE: diff --git a/src/makefile.mingw b/src/makefile.mingw index 55c5b7e387..5cb2c84f4d 100644 --- a/src/makefile.mingw +++ b/src/makefile.mingw @@ -83,6 +83,9 @@ OBJS= \ all: bitcoind.exe +test check: test_bitcoin.exe FORCE + test_bitcoin.exe + obj/%.o: %.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< @@ -101,4 +104,5 @@ clean: -del /Q bitcoind test_bitcoin -del /Q obj\* -del /Q obj-test\* - -del /Q build.h + +FORCE: diff --git a/src/makefile.osx b/src/makefile.osx index 2666caa918..359739bd5e 100644 --- a/src/makefile.osx +++ b/src/makefile.osx @@ -116,6 +116,9 @@ endif all: bitcoind +test check: test_bitcoin FORCE + ./test_bitcoin + # auto-generated dependencies: -include obj/*.P -include obj-test/*.P @@ -153,6 +156,6 @@ clean: -rm -f obj-test/*.o -rm -f obj/*.P -rm -f obj-test/*.P - -rm -f src/build.h + -rm -f obj/build.h FORCE: diff --git a/src/makefile.unix b/src/makefile.unix index 37a1917973..a41b57b4fc 100644 --- a/src/makefile.unix +++ b/src/makefile.unix @@ -132,6 +132,9 @@ OBJS= \ all: bitcoind +test check: test_bitcoin FORCE + ./test_bitcoin + # auto-generated dependencies: -include obj/*.P -include obj-test/*.P @@ -169,6 +172,6 @@ clean: -rm -f obj-test/*.o -rm -f obj/*.P -rm -f obj-test/*.P - -rm -f src/build.h + -rm -f obj/build.h FORCE: diff --git a/src/netbase.cpp b/src/netbase.cpp index 4face7a1f6..daa8a8d07e 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -246,7 +246,7 @@ bool static Socks5(string strDest, int port, SOCKET& hSocket) string strSocks5("\5\1"); strSocks5 += '\000'; strSocks5 += '\003'; strSocks5 += static_cast<char>(std::min((int)strDest.size(), 255)); - strSocks5 += strDest; + strSocks5 += strDest; strSocks5 += static_cast<char>((port >> 8) & 0xFF); strSocks5 += static_cast<char>((port >> 0) & 0xFF); ret = send(hSocket, strSocks5.c_str(), strSocks5.size(), MSG_NOSIGNAL); @@ -478,7 +478,7 @@ bool ConnectSocket(const CService &addrDest, SOCKET& hSocketRet, int nTimeout) // first connect to proxy server if (!ConnectSocketDirectly(proxy.first, hSocket, nTimeout)) return false; - + // do socks negotiation switch (proxy.second) { case 4: @@ -617,8 +617,8 @@ bool CNetAddr::IsIPv6() const bool CNetAddr::IsRFC1918() const { return IsIPv4() && ( - GetByte(3) == 10 || - (GetByte(3) == 192 && GetByte(2) == 168) || + GetByte(3) == 10 || + (GetByte(3) == 192 && GetByte(2) == 168) || (GetByte(3) == 172 && (GetByte(2) >= 16 && GetByte(2) <= 31))); } diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 27b974b5c6..eeb01d7ec9 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -115,9 +115,6 @@ BitcoinGUI::BitcoinGUI(QWidget *parent): centralWidget->addWidget(addressBookPage); centralWidget->addWidget(receiveCoinsPage); centralWidget->addWidget(sendCoinsPage); -#ifdef FIRST_CLASS_MESSAGING - centralWidget->addWidget(signVerifyMessageDialog); -#endif setCentralWidget(centralWidget); // Create status bar @@ -201,6 +198,18 @@ void BitcoinGUI::createActions() overviewAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_1)); tabGroup->addAction(overviewAction); + sendCoinsAction = new QAction(QIcon(":/icons/send"), tr("&Send coins"), this); + sendCoinsAction->setToolTip(tr("Send coins to a Bitcoin address")); + sendCoinsAction->setCheckable(true); + sendCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_2)); + tabGroup->addAction(sendCoinsAction); + + receiveCoinsAction = new QAction(QIcon(":/icons/receiving_addresses"), tr("&Receive coins"), this); + receiveCoinsAction->setToolTip(tr("Show the list of addresses for receiving payments")); + receiveCoinsAction->setCheckable(true); + receiveCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_3)); + tabGroup->addAction(receiveCoinsAction); + historyAction = new QAction(QIcon(":/icons/history"), tr("&Transactions"), this); historyAction->setToolTip(tr("Browse transaction history")); historyAction->setCheckable(true); @@ -213,52 +222,16 @@ void BitcoinGUI::createActions() addressBookAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_5)); tabGroup->addAction(addressBookAction); - receiveCoinsAction = new QAction(QIcon(":/icons/receiving_addresses"), tr("&Receive coins"), this); - receiveCoinsAction->setToolTip(tr("Show the list of addresses for receiving payments")); - receiveCoinsAction->setCheckable(true); - receiveCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_3)); - tabGroup->addAction(receiveCoinsAction); - - sendCoinsAction = new QAction(QIcon(":/icons/send"), tr("&Send coins"), this); - sendCoinsAction->setToolTip(tr("Send coins to a Bitcoin address")); - sendCoinsAction->setCheckable(true); - sendCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_2)); - tabGroup->addAction(sendCoinsAction); - - signMessageAction = new QAction(QIcon(":/icons/edit"), tr("Sign &message..."), this); - signMessageAction->setToolTip(tr("Sign a message to prove you own a Bitcoin address")); - tabGroup->addAction(signMessageAction); - - verifyMessageAction = new QAction(QIcon(":/icons/transaction_0"), tr("&Verify message..."), this); - verifyMessageAction->setToolTip(tr("Verify a message to ensure it was signed with a specified Bitcoin address")); - tabGroup->addAction(verifyMessageAction); - -#ifdef FIRST_CLASS_MESSAGING - firstClassMessagingAction = new QAction(QIcon(":/icons/edit"), tr("S&ignatures"), this); - firstClassMessagingAction->setToolTip(signMessageAction->toolTip() + QString(". / ") + verifyMessageAction->toolTip() + QString(".")); - firstClassMessagingAction->setCheckable(true); - tabGroup->addAction(firstClassMessagingAction); -#endif - connect(overviewAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); connect(overviewAction, SIGNAL(triggered()), this, SLOT(gotoOverviewPage())); + connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); + connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(gotoSendCoinsPage())); + connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); + connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage())); connect(historyAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); connect(historyAction, SIGNAL(triggered()), this, SLOT(gotoHistoryPage())); connect(addressBookAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); connect(addressBookAction, SIGNAL(triggered()), this, SLOT(gotoAddressBookPage())); - connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); - connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage())); - connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); - connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(gotoSendCoinsPage())); - connect(signMessageAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); - connect(signMessageAction, SIGNAL(triggered()), this, SLOT(gotoSignMessageTab())); - connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); - connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(gotoVerifyMessageTab())); -#ifdef FIRST_CLASS_MESSAGING - connect(firstClassMessagingAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); - // Always start with the sign message tab for FIRST_CLASS_MESSAGING - connect(firstClassMessagingAction, SIGNAL(triggered()), this, SLOT(gotoSignMessageTab())); -#endif quitAction = new QAction(QIcon(":/icons/quit"), tr("E&xit"), this); quitAction->setToolTip(tr("Quit application")); @@ -274,8 +247,6 @@ void BitcoinGUI::createActions() optionsAction->setToolTip(tr("Modify configuration options for Bitcoin")); optionsAction->setMenuRole(QAction::PreferencesRole); toggleHideAction = new QAction(QIcon(":/icons/bitcoin"), tr("&Show / Hide"), this); - exportAction = new QAction(QIcon(":/icons/export"), tr("&Export..."), this); - exportAction->setToolTip(tr("Export the data in the current tab to a file")); encryptWalletAction = new QAction(QIcon(":/icons/lock_closed"), tr("&Encrypt Wallet..."), this); encryptWalletAction->setToolTip(tr("Encrypt or decrypt wallet")); encryptWalletAction->setCheckable(true); @@ -283,17 +254,24 @@ void BitcoinGUI::createActions() backupWalletAction->setToolTip(tr("Backup wallet to another location")); changePassphraseAction = new QAction(QIcon(":/icons/key"), tr("&Change Passphrase..."), this); changePassphraseAction->setToolTip(tr("Change the passphrase used for wallet encryption")); + signMessageAction = new QAction(QIcon(":/icons/edit"), tr("Sign &message..."), this); + verifyMessageAction = new QAction(QIcon(":/icons/transaction_0"), tr("&Verify message..."), this); + + exportAction = new QAction(QIcon(":/icons/export"), tr("&Export..."), this); + exportAction->setToolTip(tr("Export the data in the current tab to a file")); openRPCConsoleAction = new QAction(QIcon(":/icons/debugwindow"), tr("&Debug window"), this); openRPCConsoleAction->setToolTip(tr("Open debugging and diagnostic console")); connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); - connect(optionsAction, SIGNAL(triggered()), this, SLOT(optionsClicked())); connect(aboutAction, SIGNAL(triggered()), this, SLOT(aboutClicked())); connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt())); + connect(optionsAction, SIGNAL(triggered()), this, SLOT(optionsClicked())); connect(toggleHideAction, SIGNAL(triggered()), this, SLOT(toggleHidden())); connect(encryptWalletAction, SIGNAL(triggered(bool)), this, SLOT(encryptWallet(bool))); connect(backupWalletAction, SIGNAL(triggered()), this, SLOT(backupWallet())); connect(changePassphraseAction, SIGNAL(triggered()), this, SLOT(changePassphrase())); + connect(signMessageAction, SIGNAL(triggered()), this, SLOT(gotoSignMessageTab())); + connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(gotoVerifyMessageTab())); } void BitcoinGUI::createMenuBar() @@ -310,10 +288,8 @@ void BitcoinGUI::createMenuBar() QMenu *file = appMenuBar->addMenu(tr("&File")); file->addAction(backupWalletAction); file->addAction(exportAction); -#ifndef FIRST_CLASS_MESSAGING file->addAction(signMessageAction); file->addAction(verifyMessageAction); -#endif file->addSeparator(); file->addAction(quitAction); @@ -339,9 +315,6 @@ void BitcoinGUI::createToolBars() toolbar->addAction(receiveCoinsAction); toolbar->addAction(historyAction); toolbar->addAction(addressBookAction); -#ifdef FIRST_CLASS_MESSAGING - toolbar->addAction(firstClassMessagingAction); -#endif QToolBar *toolbar2 = addToolBar(tr("Actions toolbar")); toolbar2->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); @@ -441,9 +414,7 @@ void BitcoinGUI::createTrayIcon() trayIconMenu->addSeparator(); trayIconMenu->addAction(sendCoinsAction); trayIconMenu->addAction(receiveCoinsAction); -#ifndef FIRST_CLASS_MESSAGING trayIconMenu->addSeparator(); -#endif trayIconMenu->addAction(signMessageAction); trayIconMenu->addAction(verifyMessageAction); trayIconMenu->addSeparator(); @@ -501,7 +472,7 @@ void BitcoinGUI::setNumConnections(int count) void BitcoinGUI::setNumBlocks(int count, int nTotalBlocks) { - // don't show / hide progressBar and its label if we have no connection(s) to the network + // don't show / hide progress bar and its label if we have no connection to the network if (!clientModel || clientModel->getNumConnections() == 0) { progressBarLabel->setVisible(false); @@ -539,7 +510,7 @@ void BitcoinGUI::setNumBlocks(int count, int nTotalBlocks) tooltip = tr("Downloaded %1 blocks of transaction history.").arg(count); } - // Override progressBarLabel text and hide progressBar, when we have warnings to display + // Override progressBarLabel text and hide progress bar, when we have warnings to display if (!strStatusBarWarnings.isEmpty()) { progressBarLabel->setText(strStatusBarWarnings); @@ -747,18 +718,8 @@ void BitcoinGUI::gotoSendCoinsPage() void BitcoinGUI::gotoSignMessageTab(QString addr) { -#ifdef FIRST_CLASS_MESSAGING - firstClassMessagingAction->setChecked(true); - centralWidget->setCurrentWidget(signVerifyMessageDialog); - - exportAction->setEnabled(false); - disconnect(exportAction, SIGNAL(triggered()), 0, 0); - - signVerifyMessageDialog->showTab_SM(false); -#else // call show() in showTab_SM() signVerifyMessageDialog->showTab_SM(true); -#endif if(!addr.isEmpty()) signVerifyMessageDialog->setAddress_SM(addr); @@ -766,18 +727,8 @@ void BitcoinGUI::gotoSignMessageTab(QString addr) void BitcoinGUI::gotoVerifyMessageTab(QString addr) { -#ifdef FIRST_CLASS_MESSAGING - firstClassMessagingAction->setChecked(true); - centralWidget->setCurrentWidget(signVerifyMessageDialog); - - exportAction->setEnabled(false); - disconnect(exportAction, SIGNAL(triggered()), 0, 0); - - signVerifyMessageDialog->showTab_VM(false); -#else // call show() in showTab_VM() signVerifyMessageDialog->showTab_VM(true); -#endif if(!addr.isEmpty()) signVerifyMessageDialog->setAddress_VM(addr); diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index acf84eb941..7f2022c28b 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -80,7 +80,6 @@ private: QAction *addressBookAction; QAction *signMessageAction; QAction *verifyMessageAction; - QAction *firstClassMessagingAction; QAction *aboutAction; QAction *receiveCoinsAction; QAction *optionsAction; diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 7d5b6fed53..8a6dafcf74 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -199,6 +199,7 @@ RPCConsole::RPCConsole(QWidget *parent) : // Install event filter for up and down arrow ui->lineEdit->installEventFilter(this); + ui->messagesWidget->installEventFilter(this); connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear())); @@ -218,15 +219,34 @@ RPCConsole::~RPCConsole() bool RPCConsole::eventFilter(QObject* obj, QEvent *event) { - if(obj == ui->lineEdit) + if(event->type() == QEvent::KeyPress) // Special key handling { - if(event->type() == QEvent::KeyPress) + QKeyEvent *keyevt = static_cast<QKeyEvent*>(event); + int key = keyevt->key(); + Qt::KeyboardModifiers mod = keyevt->modifiers(); + switch(key) { - QKeyEvent *key = static_cast<QKeyEvent*>(event); - switch(key->key()) + case Qt::Key_Up: if(obj == ui->lineEdit) { browseHistory(-1); return true; } break; + case Qt::Key_Down: if(obj == ui->lineEdit) { browseHistory(1); return true; } break; + case Qt::Key_PageUp: /* pass paging keys to messages widget */ + case Qt::Key_PageDown: + if(obj == ui->lineEdit) { - case Qt::Key_Up: browseHistory(-1); return true; - case Qt::Key_Down: browseHistory(1); return true; + QApplication::postEvent(ui->messagesWidget, new QKeyEvent(*keyevt)); + return true; + } + break; + default: + // Typing in messages widget brings focus to line edit, and redirects key there + // Exclude most combinations and keys that emit no text, except paste shortcuts + if(obj == ui->messagesWidget && ( + (!mod && !keyevt->text().isEmpty() && key != Qt::Key_Tab) || + ((mod & Qt::ControlModifier) && key == Qt::Key_V) || + ((mod & Qt::ShiftModifier) && key == Qt::Key_Insert))) + { + ui->lineEdit->setFocus(); + QApplication::postEvent(ui->lineEdit, new QKeyEvent(*keyevt)); + return true; } } } diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index cc60e2732b..4c3071984f 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -9,18 +9,8 @@ bool TransactionRecord::showTransaction(const CWalletTx &wtx) { if (wtx.IsCoinBase()) { - // Don't show generated coin until confirmed by at least one block after it - // so we don't get the user's hopes up until it looks like it's probably accepted. - // - // It is not an error when generated blocks are not accepted. By design, - // some percentage of blocks, like 10% or more, will end up not accepted. - // This is the normal mechanism by which the network copes with latency. - // - // We display regular transactions right away before any confirmation - // because they can always get into some block eventually. Generated coins - // are special because if their block is not accepted, they are not valid. - // - if (wtx.GetDepthInMainChain() < 2) + // Ensures we show generated coins / mined transactions at depth 1 + if (!wtx.IsInMainChain()) { return false; } diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index f0038dea9f..491297eb1d 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -61,7 +61,7 @@ Value getpeerinfo(const Array& params, bool fHelp) ret.push_back(obj); } - + return ret; } diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index 929dde9c15..3d0d05de84 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -573,7 +573,7 @@ Value movecmd(const Array& params, bool fHelp) // Debit CAccountingEntry debit; - debit.nOrderPos = pwalletMain->nOrderPosNext++; + debit.nOrderPos = pwalletMain->IncOrderPosNext(); debit.strAccount = strFrom; debit.nCreditDebit = -nAmount; debit.nTime = nNow; @@ -583,7 +583,7 @@ Value movecmd(const Array& params, bool fHelp) // Credit CAccountingEntry credit; - credit.nOrderPos = pwalletMain->nOrderPosNext++; + credit.nOrderPos = pwalletMain->IncOrderPosNext(); credit.strAccount = strTo; credit.nCreditDebit = nAmount; credit.nTime = nNow; diff --git a/src/sync.cpp b/src/sync.cpp index 54ad7de4e6..1ac4403beb 100644 --- a/src/sync.cpp +++ b/src/sync.cpp @@ -105,7 +105,7 @@ static void push_lock(void* c, const CLockLocation& locklocation, bool fTry) static void pop_lock() { - if (fDebug) + if (fDebug) { const CLockLocation& locklocation = (*lockstack).rbegin()->second; printf("Unlocked: %s\n", locklocation.ToString().c_str()); diff --git a/src/test/accounting_tests.cpp b/src/test/accounting_tests.cpp index c474fd65c1..8ac657288b 100644 --- a/src/test/accounting_tests.cpp +++ b/src/test/accounting_tests.cpp @@ -60,7 +60,7 @@ BOOST_AUTO_TEST_CASE(acc_orderupgrade) ae.nTime = 1333333330; ae.strOtherAccount = "d"; - ae.nOrderPos = pwalletMain->nOrderPosNext++; + ae.nOrderPos = pwalletMain->IncOrderPosNext(); walletdb.WriteAccountingEntry(ae); GetResults(walletdb, results); diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json index 432dd3f496..f01ee06cfa 100644 --- a/src/test/data/tx_invalid.json +++ b/src/test/data/tx_invalid.json @@ -21,6 +21,44 @@ ["An invalid P2SH Transaction"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x7a052c840ba73af26755de42cf01cc9e0a49fef0 EQUAL"]], -"010000000100010000000000000000000000000000000000000000000000000000000000000000000009085768617420697320ffffffff010000000000000000015100000000", true] +"010000000100010000000000000000000000000000000000000000000000000000000000000000000009085768617420697320ffffffff010000000000000000015100000000", true], +["Tests for CTransaction::CheckTransaction()"], +["No inputs"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x7a052c840ba73af26755de42cf01cc9e0a49fef0 EQUAL"]], +"0100000000010000000000000000015100000000", true], + +["No outputs"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x05ab9e14d983742513f0f451e105ffb4198d1dd4 EQUAL"]], +"01000000010001000000000000000000000000000000000000000000000000000000000000000000006d483045022100f16703104aab4e4088317c862daec83440242411b039d14280e03dd33b487ab802201318a7be236672c5c56083eb7a5a195bc57a40af7923ff8545016cd3b571e2a601232103c40e5d339df3f30bf753e7e04450ae4ef76c9e45587d1d993bdc4cd06f0651c7acffffffff0000000000", true], + +["Negative output"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0xae609aca8061d77c5e111f6bb62501a6bbe2bfdb EQUAL"]], +"01000000010001000000000000000000000000000000000000000000000000000000000000000000006d4830450220063222cbb128731fc09de0d7323746539166544d6c1df84d867ccea84bcc8903022100bf568e8552844de664cd41648a031554327aa8844af34b4f27397c65b92c04de0123210243ec37dee0e2e053a9c976f43147e79bc7d9dc606ea51010af1ac80db6b069e1acffffffff01ffffffffffffffff015100000000", true], + +["MAX_MONEY + 1 output"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x32afac281462b822adbec5094b8d4d337dd5bd6a EQUAL"]], +"01000000010001000000000000000000000000000000000000000000000000000000000000000000006e493046022100e1eadba00d9296c743cb6ecc703fd9ddc9b3cd12906176a226ae4c18d6b00796022100a71aef7d2874deff681ba6080f1b278bac7bb99c61b08a85f4311970ffe7f63f012321030c0588dc44d92bdcbf8e72093466766fdc265ead8db64517b0c542275b70fffbacffffffff010140075af0750700015100000000", true], + +["MAX_MONEY output + 1 output"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0xb558cbf4930954aa6a344363a15668d7477ae716 EQUAL"]], +"01000000010001000000000000000000000000000000000000000000000000000000000000000000006d483045022027deccc14aa6668e78a8c9da3484fbcd4f9dcc9bb7d1b85146314b21b9ae4d86022100d0b43dece8cfb07348de0ca8bc5b86276fa88f7f2138381128b7c36ab2e42264012321029bb13463ddd5d2cc05da6e84e37536cb9525703cfd8f43afdb414988987a92f6acffffffff020040075af075070001510001000000000000015100000000", true], + +["Duplicate inputs"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x236d0639db62b0773fd8ac34dc85ae19e9aba80a EQUAL"]], +"01000000020001000000000000000000000000000000000000000000000000000000000000000000006c47304402204bb1197053d0d7799bf1b30cd503c44b58d6240cccbdc85b6fe76d087980208f02204beeed78200178ffc6c74237bb74b3f276bbb4098b5605d814304fe128bf1431012321039e8815e15952a7c3fada1905f8cf55419837133bd7756c0ef14fc8dfe50c0deaacffffffff0001000000000000000000000000000000000000000000000000000000000000000000006c47304402202306489afef52a6f62e90bf750bbcdf40c06f5c6b138286e6b6b86176bb9341802200dba98486ea68380f47ebb19a7df173b99e6bc9c681d6ccf3bde31465d1f16b3012321039e8815e15952a7c3fada1905f8cf55419837133bd7756c0ef14fc8dfe50c0deaacffffffff010000000000000000015100000000", true], + +["Coinbase of size 1"], +["Note the input is just required to make the tester happy"], +[[["0000000000000000000000000000000000000000000000000000000000000000", -1, "1"]], +"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0151ffffffff010000000000000000015100000000", true], + +["Coinbase of size 101"], +["Note the input is just required to make the tester happy"], +[[["0000000000000000000000000000000000000000000000000000000000000000", -1, "1"]], +"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff655151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151ffffffff010000000000000000015100000000", true], + +["Null txin"], +[[["0000000000000000000000000000000000000000000000000000000000000000", -1, "HASH160 0x14 0x02dae7dbbda56097959cba59b1989dd3e47937bf EQUAL"]], +"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff6e49304602210086f39e028e46dafa8e1e3be63906465f4cf038fbe5ed6403dc3e74ae876e6431022100c4625c675cfc5c7e3a0e0d7eaec92ac24da20c73a88eb40d09253e51ac6def5201232103a183ddc41e84753aca47723c965d1b5c8b0e2b537963518355e6dd6cf8415e50acffffffff010000000000000000015100000000", true] ] diff --git a/src/test/data/tx_valid.json b/src/test/data/tx_valid.json index cc4b28f6b4..5528ae7243 100644 --- a/src/test/data/tx_valid.json +++ b/src/test/data/tx_valid.json @@ -48,5 +48,24 @@ ["A valid P2SH Transaction using the standard transaction type put forth in BIP 16"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x8febbed40483661de6958d957412f82deed8e2f7 EQUAL"]], -"01000000010001000000000000000000000000000000000000000000000000000000000000000000006e493046022100c66c9cdf4c43609586d15424c54707156e316d88b0a1534c9e6b0d4f311406310221009c0fe51dbc9c4ab7cc25d3fdbeccf6679fe6827f08edf2b4a9f16ee3eb0e438a0123210338e8034509af564c62644c07691942e0c056752008a173c89f60ab2a88ac2ebfacffffffff010000000000000000015100000000", true] +"01000000010001000000000000000000000000000000000000000000000000000000000000000000006e493046022100c66c9cdf4c43609586d15424c54707156e316d88b0a1534c9e6b0d4f311406310221009c0fe51dbc9c4ab7cc25d3fdbeccf6679fe6827f08edf2b4a9f16ee3eb0e438a0123210338e8034509af564c62644c07691942e0c056752008a173c89f60ab2a88ac2ebfacffffffff010000000000000000015100000000", true], + +["Tests for CTransaction::CheckTransaction()"], +["MAX_MONEY output"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x32afac281462b822adbec5094b8d4d337dd5bd6a EQUAL"]], +"01000000010001000000000000000000000000000000000000000000000000000000000000000000006e493046022100e1eadba00d9296c743cb6ecc703fd9ddc9b3cd12906176a226ae4c18d6b00796022100a71aef7d2874deff681ba6080f1b278bac7bb99c61b08a85f4311970ffe7f63f012321030c0588dc44d92bdcbf8e72093466766fdc265ead8db64517b0c542275b70fffbacffffffff010040075af0750700015100000000", true], + +["MAX_MONEY output + 0 output"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0xb558cbf4930954aa6a344363a15668d7477ae716 EQUAL"]], +"01000000010001000000000000000000000000000000000000000000000000000000000000000000006d483045022027deccc14aa6668e78a8c9da3484fbcd4f9dcc9bb7d1b85146314b21b9ae4d86022100d0b43dece8cfb07348de0ca8bc5b86276fa88f7f2138381128b7c36ab2e42264012321029bb13463ddd5d2cc05da6e84e37536cb9525703cfd8f43afdb414988987a92f6acffffffff020040075af075070001510000000000000000015100000000", true], + +["Coinbase of size 2"], +["Note the input is just required to make the tester happy"], +[[["0000000000000000000000000000000000000000000000000000000000000000", -1, "1"]], +"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff025151ffffffff010000000000000000015100000000", true], + +["Coinbase of size 100"], +["Note the input is just required to make the tester happy"], +[[["0000000000000000000000000000000000000000000000000000000000000000", -1, "1"]], +"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff6451515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151ffffffff010000000000000000015100000000", true] ] diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index de6e18f14d..c230458866 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -66,6 +66,8 @@ BOOST_AUTO_TEST_CASE(tx_valid) CTransaction tx; stream >> tx; + BOOST_CHECK_MESSAGE(tx.CheckTransaction(), strTest); + for (unsigned int i = 0; i < tx.vin.size(); i++) { if (!mapprevOutScriptPubKeys.count(tx.vin[i].prevout)) @@ -131,7 +133,9 @@ BOOST_AUTO_TEST_CASE(tx_invalid) CTransaction tx; stream >> tx; - for (unsigned int i = 0; i < tx.vin.size(); i++) + fValid = tx.CheckTransaction(); + + for (unsigned int i = 0; i < tx.vin.size() && fValid; i++) { if (!mapprevOutScriptPubKeys.count(tx.vin[i].prevout)) { @@ -139,8 +143,10 @@ BOOST_AUTO_TEST_CASE(tx_invalid) break; } - BOOST_CHECK_MESSAGE(!VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], tx, i, test[2].get_bool(), 0), strTest); + fValid = VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], tx, i, test[2].get_bool(), 0); } + + BOOST_CHECK_MESSAGE(!fValid, strTest); } } } diff --git a/src/util.h b/src/util.h index 65923e68a3..2409ccb79c 100644 --- a/src/util.h +++ b/src/util.h @@ -483,7 +483,7 @@ inline uint160 Hash160(const std::vector<unsigned char>& vch) } -/** Median filter over a stream of values. +/** Median filter over a stream of values. * Returns the median of the last N numbers */ template <typename T> class CMedianFilter @@ -500,7 +500,7 @@ public: vValues.push_back(initial_value); vSorted = vValues; } - + void input(T value) { if(vValues.size() == nSize) diff --git a/src/wallet.cpp b/src/wallet.cpp index f88a0e1413..a10f187309 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -291,6 +291,13 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) return true; } +int64 CWallet::IncOrderPosNext() +{ + int64 nRet = nOrderPosNext; + CWalletDB(strWalletFile).WriteOrderPosNext(++nOrderPosNext); + return nRet; +} + CWallet::TxItems CWallet::OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount) { CWalletDB walletdb(strWalletFile); @@ -362,7 +369,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn) if (fInsertedNew) { wtx.nTimeReceived = GetAdjustedTime(); - wtx.nOrderPos = nOrderPosNext++; + wtx.nOrderPos = IncOrderPosNext(); wtx.nTimeSmart = wtx.nTimeReceived; if (wtxIn.hashBlock != 0) @@ -953,7 +960,7 @@ int64 CWallet::GetImmatureBalance() const for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) { const CWalletTx& pcoin = (*it).second; - if (pcoin.IsCoinBase() && pcoin.GetBlocksToMaturity() > 0 && pcoin.GetDepthInMainChain() >= 2) + if (pcoin.IsCoinBase() && pcoin.GetBlocksToMaturity() > 0 && pcoin.IsInMainChain()) nTotal += GetCredit(pcoin); } } diff --git a/src/wallet.h b/src/wallet.h index 7fd33629fe..22795b75ba 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -98,6 +98,7 @@ public: fFileBacked = false; nMasterKeyMaxID = 0; pwalletdbEncryption = NULL; + nOrderPosNext = 0; } CWallet(std::string strWalletFileIn) { @@ -107,6 +108,7 @@ public: fFileBacked = true; nMasterKeyMaxID = 0; pwalletdbEncryption = NULL; + nOrderPosNext = 0; } std::map<uint256, CWalletTx> mapWallet; @@ -144,6 +146,11 @@ public: bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase); bool EncryptWallet(const SecureString& strWalletPassphrase); + /** Increment the next transaction order id + @return next transaction order id + */ + int64 IncOrderPosNext(); + typedef std::pair<CWalletTx*, CAccountingEntry*> TxPair; typedef std::multimap<int64, TxPair > TxItems; @@ -346,7 +353,7 @@ static void WriteOrderPos(const int64& nOrderPos, mapValue_t& mapValue) } -/** A transaction with a bunch of additional info that only the owner cares about. +/** A transaction with a bunch of additional info that only the owner cares about. * It includes any unrecorded transactions needed to link it back to the block chain. */ class CWalletTx : public CMerkleTx diff --git a/src/walletdb.cpp b/src/walletdb.cpp index 164b68e11f..0fac0109c8 100644 --- a/src/walletdb.cpp +++ b/src/walletdb.cpp @@ -392,6 +392,10 @@ int CWalletDB::LoadWallet(CWallet* pwallet) return DB_CORRUPT; } } + else if (strType == "orderposnext") + { + ssValue >> pwallet->nOrderPosNext; + } } pcursor->close(); } diff --git a/src/walletdb.h b/src/walletdb.h index 187be65a97..d339d4c3f1 100644 --- a/src/walletdb.h +++ b/src/walletdb.h @@ -115,6 +115,12 @@ public: return Read(std::string("bestblock"), locator); } + bool WriteOrderPosNext(int64 nOrderPosNext) + { + nWalletDBUpdated++; + return Write(std::string("orderposnext"), nOrderPosNext); + } + bool ReadDefaultKey(std::vector<unsigned char>& vchPubKey) { vchPubKey.clear(); |