aboutsummaryrefslogtreecommitdiff
path: root/ui.cpp
diff options
context:
space:
mode:
authors_nakamoto <s_nakamoto@1a98c847-1fd6-4fd8-948a-caf3550aa51b>2010-02-12 20:38:44 +0000
committers_nakamoto <s_nakamoto@1a98c847-1fd6-4fd8-948a-caf3550aa51b>2010-02-12 20:38:44 +0000
commit98500d70a8cf25af4bab80526fd128ccdc36ceeb (patch)
tree61624e0903150505dc09977ae9ff1bc9ab40ee2b /ui.cpp
parentfa9dbd6b62ab161c29c9b8cf97b9c8da8ef4346e (diff)
command line and JSON-RPC first draft, requires Boost 1.35 or higher for boost::asio,
added SetBitcoinAddress and GetBitcoinAddress methods on CScript, critsect interlocks around mapAddressBook, added some random delays in tx broadcast to improve privacy, now compiles with MSVC 8.0 git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@60 1a98c847-1fd6-4fd8-948a-caf3550aa51b
Diffstat (limited to 'ui.cpp')
-rw-r--r--ui.cpp436
1 files changed, 233 insertions, 203 deletions
diff --git a/ui.cpp b/ui.cpp
index 5d93ad227f..586200d6ef 100644
--- a/ui.cpp
+++ b/ui.cpp
@@ -21,7 +21,6 @@ DEFINE_EVENT_TYPE(wxEVT_REPLY3)
CMainFrame* pframeMain = NULL;
CMyTaskBarIcon* ptaskbaricon = NULL;
-map<string, string> mapAddressBook;
bool fRandSendTest = false;
void RandSend();
extern int g_isPainting;
@@ -177,8 +176,11 @@ void CalledMessageBox(const string& message, const string& caption, int style, w
int ThreadSafeMessageBox(const string& message, const string& caption, int style, wxWindow* parent, int x, int y)
{
- if (mapArgs.count("-noui"))
+ if (fDaemon)
+ {
+ printf("wxMessageBox %s: %s\n", caption.c_str(), message.c_str());
return wxOK;
+ }
#ifdef __WXMSW__
return wxMessageBox(message, caption, style, parent, x, y);
@@ -413,7 +415,7 @@ void Shutdown(void* parg)
StopNode();
DBFlush(true);
CreateThread(ExitTimeout, NULL);
- Sleep(10);
+ Sleep(50);
printf("Bitcoin exiting\n\n");
fExit = true;
exit(0);
@@ -697,19 +699,22 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex)
vector<unsigned char> vchPubKey;
if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey))
{
- string strAddress = PubKeyToAddress(vchPubKey);
- if (mapAddressBook.count(strAddress))
+ CRITICAL_BLOCK(cs_mapAddressBook)
{
- //strDescription += "Received payment to ";
- //strDescription += "Received with address ";
- strDescription += "From: unknown, To: ";
- strDescription += strAddress;
- /// The labeling feature is just too confusing, so I hid it
- /// by putting it at the end where it runs off the screen.
- /// It can still be seen by widening the column, or in the
- /// details dialog.
- if (!mapAddressBook[strAddress].empty())
- strDescription += " (" + mapAddressBook[strAddress] + ")";
+ string strAddress = PubKeyToAddress(vchPubKey);
+ if (mapAddressBook.count(strAddress))
+ {
+ //strDescription += "Received payment to ";
+ //strDescription += "Received with address ";
+ strDescription += "From: unknown, To: ";
+ strDescription += strAddress;
+ /// The labeling feature is just too confusing, so I hid it
+ /// by putting it at the end where it runs off the screen.
+ /// It can still be seen by widening the column, or in the
+ /// details dialog.
+ if (!mapAddressBook[strAddress].empty())
+ strDescription += " (" + mapAddressBook[strAddress] + ")";
+ }
}
}
break;
@@ -776,8 +781,9 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex)
}
string strDescription = "To: ";
- if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty())
- strDescription += mapAddressBook[strAddress] + " ";
+ CRITICAL_BLOCK(cs_mapAddressBook)
+ if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty())
+ strDescription += mapAddressBook[strAddress] + " ";
strDescription += strAddress;
if (!mapValue["message"].empty())
{
@@ -1273,238 +1279,241 @@ void CMainFrame::OnListItemActivatedOrdersReceived(wxListEvent& event)
CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetailsDialogBase(parent)
{
- string strHTML;
- strHTML.reserve(4000);
- strHTML += "<html><font face='verdana, arial, helvetica, sans-serif'>";
+ CRITICAL_BLOCK(cs_mapAddressBook)
+ {
+ string strHTML;
+ strHTML.reserve(4000);
+ strHTML += "<html><font face='verdana, arial, helvetica, sans-serif'>";
- int64 nTime = wtx.GetTxTime();
- int64 nCredit = wtx.GetCredit();
- int64 nDebit = wtx.GetDebit();
- int64 nNet = nCredit - nDebit;
+ int64 nTime = wtx.GetTxTime();
+ int64 nCredit = wtx.GetCredit();
+ int64 nDebit = wtx.GetDebit();
+ int64 nNet = nCredit - nDebit;
- strHTML += "<b>Status:</b> " + FormatTxStatus(wtx);
- int nRequests = wtx.GetRequestCount();
- if (nRequests != -1)
- {
- if (nRequests == 0)
- strHTML += ", has not been successfully broadcast yet";
- else if (nRequests == 1)
- strHTML += strprintf(", broadcast through %d node", nRequests);
- else
- strHTML += strprintf(", broadcast through %d nodes", nRequests);
- }
- strHTML += "<br>";
+ strHTML += "<b>Status:</b> " + FormatTxStatus(wtx);
+ int nRequests = wtx.GetRequestCount();
+ if (nRequests != -1)
+ {
+ if (nRequests == 0)
+ strHTML += ", has not been successfully broadcast yet";
+ else if (nRequests == 1)
+ strHTML += strprintf(", broadcast through %d node", nRequests);
+ else
+ strHTML += strprintf(", broadcast through %d nodes", nRequests);
+ }
+ strHTML += "<br>";
- strHTML += "<b>Date:</b> " + (nTime ? DateTimeStr(nTime) : "") + "<br>";
+ strHTML += "<b>Date:</b> " + (nTime ? DateTimeStr(nTime) : "") + "<br>";
- //
- // From
- //
- if (wtx.IsCoinBase())
- {
- strHTML += "<b>Source:</b> Generated<br>";
- }
- else if (!wtx.mapValue["from"].empty())
- {
- // Online transaction
- if (!wtx.mapValue["from"].empty())
- strHTML += "<b>From:</b> " + HtmlEscape(wtx.mapValue["from"]) + "<br>";
- }
- else
- {
- // Offline transaction
- if (nNet > 0)
+ //
+ // From
+ //
+ if (wtx.IsCoinBase())
{
- // Credit
- foreach(const CTxOut& txout, wtx.vout)
+ strHTML += "<b>Source:</b> Generated<br>";
+ }
+ else if (!wtx.mapValue["from"].empty())
+ {
+ // Online transaction
+ if (!wtx.mapValue["from"].empty())
+ strHTML += "<b>From:</b> " + HtmlEscape(wtx.mapValue["from"]) + "<br>";
+ }
+ else
+ {
+ // Offline transaction
+ if (nNet > 0)
{
- if (txout.IsMine())
+ // Credit
+ foreach(const CTxOut& txout, wtx.vout)
{
- vector<unsigned char> vchPubKey;
- if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey))
+ if (txout.IsMine())
{
- string strAddress = PubKeyToAddress(vchPubKey);
- if (mapAddressBook.count(strAddress))
+ vector<unsigned char> vchPubKey;
+ if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey))
{
- strHTML += "<b>From:</b> unknown<br>";
- strHTML += "<b>To:</b> ";
- strHTML += HtmlEscape(strAddress);
- if (!mapAddressBook[strAddress].empty())
- strHTML += " (yours, label: " + mapAddressBook[strAddress] + ")";
- else
- strHTML += " (yours)";
- strHTML += "<br>";
+ string strAddress = PubKeyToAddress(vchPubKey);
+ if (mapAddressBook.count(strAddress))
+ {
+ strHTML += "<b>From:</b> unknown<br>";
+ strHTML += "<b>To:</b> ";
+ strHTML += HtmlEscape(strAddress);
+ if (!mapAddressBook[strAddress].empty())
+ strHTML += " (yours, label: " + mapAddressBook[strAddress] + ")";
+ else
+ strHTML += " (yours)";
+ strHTML += "<br>";
+ }
}
+ break;
}
- break;
}
}
}
- }
- //
- // To
- //
- string strAddress;
- if (!wtx.mapValue["to"].empty())
- {
- // Online transaction
- strAddress = wtx.mapValue["to"];
- strHTML += "<b>To:</b> ";
- if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty())
- strHTML += mapAddressBook[strAddress] + " ";
- strHTML += HtmlEscape(strAddress) + "<br>";
- }
-
-
- //
- // Amount
- //
- if (wtx.IsCoinBase() && nCredit == 0)
- {
- //
- // Coinbase
- //
- int64 nUnmatured = 0;
- foreach(const CTxOut& txout, wtx.vout)
- nUnmatured += txout.GetCredit();
- if (wtx.IsInMainChain())
- strHTML += strprintf("<b>Credit:</b> (%s matures in %d more blocks)<br>", FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity());
- else
- strHTML += "<b>Credit:</b> (not accepted)<br>";
- }
- else if (nNet > 0)
- {
//
- // Credit
+ // To
//
- strHTML += "<b>Credit:</b> " + FormatMoney(nNet) + "<br>";
- }
- else
- {
- bool fAllFromMe = true;
- foreach(const CTxIn& txin, wtx.vin)
- fAllFromMe = fAllFromMe && txin.IsMine();
+ string strAddress;
+ if (!wtx.mapValue["to"].empty())
+ {
+ // Online transaction
+ strAddress = wtx.mapValue["to"];
+ strHTML += "<b>To:</b> ";
+ if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty())
+ strHTML += mapAddressBook[strAddress] + " ";
+ strHTML += HtmlEscape(strAddress) + "<br>";
+ }
- bool fAllToMe = true;
- foreach(const CTxOut& txout, wtx.vout)
- fAllToMe = fAllToMe && txout.IsMine();
- if (fAllFromMe)
+ //
+ // Amount
+ //
+ if (wtx.IsCoinBase() && nCredit == 0)
{
//
- // Debit
+ // Coinbase
//
+ int64 nUnmatured = 0;
foreach(const CTxOut& txout, wtx.vout)
- {
- if (txout.IsMine())
- continue;
+ nUnmatured += txout.GetCredit();
+ if (wtx.IsInMainChain())
+ strHTML += strprintf("<b>Credit:</b> (%s matures in %d more blocks)<br>", FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity());
+ else
+ strHTML += "<b>Credit:</b> (not accepted)<br>";
+ }
+ else if (nNet > 0)
+ {
+ //
+ // Credit
+ //
+ strHTML += "<b>Credit:</b> " + FormatMoney(nNet) + "<br>";
+ }
+ else
+ {
+ bool fAllFromMe = true;
+ foreach(const CTxIn& txin, wtx.vin)
+ fAllFromMe = fAllFromMe && txin.IsMine();
+
+ bool fAllToMe = true;
+ foreach(const CTxOut& txout, wtx.vout)
+ fAllToMe = fAllToMe && txout.IsMine();
- if (wtx.mapValue["to"].empty())
+ if (fAllFromMe)
+ {
+ //
+ // Debit
+ //
+ foreach(const CTxOut& txout, wtx.vout)
{
- // Offline transaction
- uint160 hash160;
- if (ExtractHash160(txout.scriptPubKey, hash160))
+ if (txout.IsMine())
+ continue;
+
+ if (wtx.mapValue["to"].empty())
{
- string strAddress = Hash160ToAddress(hash160);
- strHTML += "<b>To:</b> ";
- if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty())
- strHTML += mapAddressBook[strAddress] + " ";
- strHTML += strAddress;
- strHTML += "<br>";
+ // Offline transaction
+ uint160 hash160;
+ if (ExtractHash160(txout.scriptPubKey, hash160))
+ {
+ string strAddress = Hash160ToAddress(hash160);
+ strHTML += "<b>To:</b> ";
+ if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty())
+ strHTML += mapAddressBook[strAddress] + " ";
+ strHTML += strAddress;
+ strHTML += "<br>";
+ }
}
+
+ strHTML += "<b>Debit:</b> " + FormatMoney(-txout.nValue) + "<br>";
}
- strHTML += "<b>Debit:</b> " + FormatMoney(-txout.nValue) + "<br>";
- }
+ 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>";
+ }
- if (fAllToMe)
+ int64 nTxFee = nDebit - wtx.GetValueOut();
+ if (nTxFee > 0)
+ strHTML += "<b>Transaction fee:</b> " + FormatMoney(-nTxFee) + "<br>";
+ }
+ else
{
- // 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>";
+ //
+ // Mixed debit transaction
+ //
+ foreach(const CTxIn& txin, wtx.vin)
+ if (txin.IsMine())
+ strHTML += "<b>Debit:</b> " + FormatMoney(-txin.GetDebit()) + "<br>";
+ foreach(const CTxOut& txout, wtx.vout)
+ if (txout.IsMine())
+ strHTML += "<b>Credit:</b> " + FormatMoney(txout.GetCredit()) + "<br>";
}
-
- int64 nTxFee = nDebit - wtx.GetValueOut();
- if (nTxFee > 0)
- strHTML += "<b>Transaction fee:</b> " + FormatMoney(-nTxFee) + "<br>";
}
- else
- {
- //
- // Mixed debit transaction
- //
- foreach(const CTxIn& txin, wtx.vin)
- if (txin.IsMine())
- strHTML += "<b>Debit:</b> " + FormatMoney(-txin.GetDebit()) + "<br>";
- foreach(const CTxOut& txout, wtx.vout)
- if (txout.IsMine())
- strHTML += "<b>Credit:</b> " + FormatMoney(txout.GetCredit()) + "<br>";
- }
- }
- strHTML += "<b>Net amount:</b> " + FormatMoney(nNet, true) + "<br>";
+ strHTML += "<b>Net amount:</b> " + FormatMoney(nNet, true) + "<br>";
- //
- // Message
- //
- if (!wtx.mapValue["message"].empty())
- strHTML += "<br><b>Message:</b><br>" + HtmlEscape(wtx.mapValue["message"], true) + "<br>";
-
- if (wtx.IsCoinBase())
- strHTML += "<br>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.<br>";
+ //
+ // Message
+ //
+ if (!wtx.mapValue["message"].empty())
+ strHTML += "<br><b>Message:</b><br>" + HtmlEscape(wtx.mapValue["message"], true) + "<br>";
+ if (wtx.IsCoinBase())
+ strHTML += "<br>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.<br>";
- //
- // Debug view
- //
- if (fDebug)
- {
- strHTML += "<hr><br>debug print<br><br>";
- foreach(const CTxIn& txin, wtx.vin)
- if (txin.IsMine())
- strHTML += "<b>Debit:</b> " + FormatMoney(-txin.GetDebit()) + "<br>";
- foreach(const CTxOut& txout, wtx.vout)
- if (txout.IsMine())
- strHTML += "<b>Credit:</b> " + FormatMoney(txout.GetCredit()) + "<br>";
- strHTML += "<b>Inputs:</b><br>";
- CRITICAL_BLOCK(cs_mapWallet)
+ //
+ // Debug view
+ //
+ if (fDebug)
{
+ strHTML += "<hr><br>debug print<br><br>";
foreach(const CTxIn& txin, wtx.vin)
+ if (txin.IsMine())
+ strHTML += "<b>Debit:</b> " + FormatMoney(-txin.GetDebit()) + "<br>";
+ foreach(const CTxOut& txout, wtx.vout)
+ if (txout.IsMine())
+ strHTML += "<b>Credit:</b> " + FormatMoney(txout.GetCredit()) + "<br>";
+
+ strHTML += "<b>Inputs:</b><br>";
+ CRITICAL_BLOCK(cs_mapWallet)
{
- COutPoint prevout = txin.prevout;
- map<uint256, CWalletTx>::iterator mi = mapWallet.find(prevout.hash);
- if (mi != mapWallet.end())
+ foreach(const CTxIn& txin, wtx.vin)
{
- const CWalletTx& prev = (*mi).second;
- if (prevout.n < prev.vout.size())
+ COutPoint prevout = txin.prevout;
+ map<uint256, CWalletTx>::iterator mi = mapWallet.find(prevout.hash);
+ if (mi != mapWallet.end())
{
- strHTML += HtmlEscape(prev.ToString(), true);
- strHTML += " &nbsp;&nbsp; " + FormatTxStatus(prev) + ", ";
- strHTML = strHTML + "IsMine=" + (prev.vout[prevout.n].IsMine() ? "true" : "false") + "<br>";
+ const CWalletTx& prev = (*mi).second;
+ if (prevout.n < prev.vout.size())
+ {
+ strHTML += HtmlEscape(prev.ToString(), true);
+ strHTML += " &nbsp;&nbsp; " + FormatTxStatus(prev) + ", ";
+ strHTML = strHTML + "IsMine=" + (prev.vout[prevout.n].IsMine() ? "true" : "false") + "<br>";
+ }
}
}
}
- }
- strHTML += "<br><hr><br><b>Transaction:</b><br>";
- strHTML += HtmlEscape(wtx.ToString(), true);
- }
+ strHTML += "<br><hr><br><b>Transaction:</b><br>";
+ strHTML += HtmlEscape(wtx.ToString(), true);
+ }
- strHTML += "</font></html>";
- string(strHTML.begin(), strHTML.end()).swap(strHTML);
- m_htmlWin->SetPage(strHTML);
- m_buttonOK->SetFocus();
+ strHTML += "</font></html>";
+ string(strHTML.begin(), strHTML.end()).swap(strHTML);
+ m_htmlWin->SetPage(strHTML);
+ m_buttonOK->SetFocus();
+ }
}
void CTxDetailsDialog::OnButtonOK(wxCommandEvent& event)
@@ -1686,9 +1695,10 @@ CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent)
#if !wxUSE_UNICODE
// Workaround until upgrade to wxWidgets supporting UTF-8
+ // Hack to change the (c) character from UTF-8 back to ANSI
wxString str = m_staticTextMain->GetLabel();
- if (str.Find('Â') != wxNOT_FOUND)
- str.Remove(str.Find('Â'), 1);
+ if (str.Find('\xC2') != wxNOT_FOUND)
+ str.Remove(str.Find('\xC2'), 1);
m_staticTextMain->SetLabel(str);
#endif
#ifndef __WXMSW__
@@ -1843,10 +1853,11 @@ void CSendDialog::OnButtonSend(wxCommandEvent& event)
CScript scriptPubKey;
scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG;
- if (!SendMoney(scriptPubKey, nValue, wtx))
- return;
-
- wxMessageBox("Payment sent ", "Sending...");
+ string strError = SendMoney(scriptPubKey, nValue, wtx);
+ if (strError != "")
+ wxMessageBox(strError + " ", "Sending...");
+ else
+ wxMessageBox("Payment sent ", "Sending...");
}
else
{
@@ -1869,8 +1880,9 @@ void CSendDialog::OnButtonSend(wxCommandEvent& event)
return;
}
- if (!mapAddressBook.count(strAddress))
- SetAddressBookName(strAddress, "");
+ CRITICAL_BLOCK(cs_mapAddressBook)
+ if (!mapAddressBook.count(strAddress))
+ SetAddressBookName(strAddress, "");
EndModal(true);
}
@@ -2227,6 +2239,7 @@ CYourAddressDialog::CYourAddressDialog(wxWindow* parent, const string& strInitSe
// Fill listctrl with address book data
CRITICAL_BLOCK(cs_mapKeys)
+ CRITICAL_BLOCK(cs_mapAddressBook)
{
foreach(const PAIRTYPE(string, string)& item, mapAddressBook)
{
@@ -2366,6 +2379,7 @@ CAddressBookDialog::CAddressBookDialog(wxWindow* parent, const wxString& strInit
// Fill listctrl with address book data
CRITICAL_BLOCK(cs_mapKeys)
+ CRITICAL_BLOCK(cs_mapAddressBook)
{
foreach(const PAIRTYPE(string, string)& item, mapAddressBook)
{
@@ -3515,6 +3529,12 @@ bool CMyApp::OnInit2()
//
// Parameters
//
+ if (argc > 1 && argv[1][0] != '-' && argv[1][0] != '/')
+ {
+ int ret = CommandLineRPC(argc, argv);
+ exit(ret);
+ }
+
ParseParameters(argc, argv);
if (mapArgs.count("-?") || mapArgs.count("--help"))
{
@@ -3557,6 +3577,13 @@ bool CMyApp::OnInit2()
if (mapArgs.count("-printtodebugger"))
fPrintToDebugger = true;
+ if (mapArgs.count("-daemon") || mapArgs.count("-d"))
+ {
+ fDaemon = true;
+ /// todo: need to fork
+ /// should it fork after the bind/single instance stuff?
+ }
+
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");
@@ -3730,7 +3757,7 @@ bool CMyApp::OnInit2()
//
// Create the main frame window
//
- if (!mapArgs.count("-noui"))
+ if (!fDaemon)
{
pframeMain = new CMainFrame(NULL);
if (mapArgs.count("-min"))
@@ -3752,6 +3779,9 @@ bool CMyApp::OnInit2()
if (!CreateThread(StartNode, NULL))
wxMessageBox("Error: CreateThread(StartNode) failed", "Bitcoin");
+ if (mapArgs.count("-server") || fDaemon)
+ CreateThread(ThreadRPCServer, NULL);
+
if (fFirstRun)
SetStartOnSystemStartup(true);