Browse Source

run as daemon without GUI,

hooked wxApp::Initialize to ignore gtk-init-check failure if no GUI,
fork to daemonize,
rpc getinfo, getconnectioncount, getbalance, getgenerate, setgenerate,
-- version 0.2.6

git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@70 1a98c847-1fd6-4fd8-948a-caf3550aa51b
0.8 v0.2.6
s_nakamoto 15 years ago
parent
commit
cb420a1dfc
  1. 5
      main.cpp
  2. 4
      main.h
  3. 110
      rpc.cpp
  4. 2
      serialize.h
  5. 94
      ui.cpp
  6. 4
      util.cpp
  7. 1
      util.h

5
main.cpp

@ -1315,8 +1315,7 @@ bool CBlock::AcceptBlock()
if (nTime <= pindexPrev->GetMedianTimePast()) if (nTime <= pindexPrev->GetMedianTimePast())
return error("AcceptBlock() : block's timestamp is too early"); return error("AcceptBlock() : block's timestamp is too early");
// Check that all transactions are finalized (starting around Mar 2010) // Check that all transactions are finalized
if (nBestHeight > 36000)
foreach(const CTransaction& tx, vtx) foreach(const CTransaction& tx, vtx)
if (!tx.IsFinal(nTime)) if (!tx.IsFinal(nTime))
return error("AcceptBlock() : contains a non-final transaction"); return error("AcceptBlock() : contains a non-final transaction");
@ -1336,7 +1335,7 @@ bool CBlock::AcceptBlock()
return error("AcceptBlock() : AddToBlockIndex failed"); return error("AcceptBlock() : AddToBlockIndex failed");
// Don't relay old inventory during initial block download. // Don't relay old inventory during initial block download.
// Please keep this constant updated to a few thousand below current block count. // Please keep this number updated to a few thousand below current block count.
if (hashBestChain == hash && nBestHeight > 40000) if (hashBestChain == hash && nBestHeight > 40000)
RelayInventory(CInv(MSG_BLOCK, hash)); RelayInventory(CInv(MSG_BLOCK, hash));

4
main.h

@ -1384,6 +1384,9 @@ public:
CPrivKey vchPrivKey; CPrivKey vchPrivKey;
int64 nTimeCreated; int64 nTimeCreated;
int64 nTimeExpires; int64 nTimeExpires;
string strComment;
//// 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 nTimeExpiresIn=0)
{ {
@ -1398,6 +1401,7 @@ public:
READWRITE(vchPrivKey); READWRITE(vchPrivKey);
READWRITE(nTimeCreated); READWRITE(nTimeCreated);
READWRITE(nTimeExpires); READWRITE(nTimeExpires);
READWRITE(strComment);
) )
}; };

110
rpc.cpp

@ -66,6 +66,17 @@ Value getblocknumber(const Array& params)
} }
Value getconnectioncount(const Array& params)
{
if (params.size() != 0)
throw runtime_error(
"getconnectioncount (no parameters)\n"
"Returns the number of connections to other nodes.");
return (int)vNodes.size();
}
Value getdifficulty(const Array& params) Value getdifficulty(const Array& params)
{ {
if (params.size() != 0) if (params.size() != 0)
@ -85,6 +96,71 @@ Value getdifficulty(const Array& params)
} }
Value getbalance(const Array& params)
{
if (params.size() != 0)
throw runtime_error(
"getbalance (no parameters)\n"
"Returns the server's available balance.");
return ((double)GetBalance() / (double)COIN);
}
Value getgenerate(const Array& params)
{
if (params.size() != 0)
throw runtime_error(
"getgenerate (no parameters)\n"
"Returns true or false.");
return (bool)fGenerateBitcoins;
}
Value setgenerate(const Array& params)
{
if (params.size() < 1 || params.size() > 2)
throw runtime_error(
"setgenerate <generate> [genproclimit]\n"
"<generate> is true or false to turn generation on or off.\n"
"Generation is limited to [genproclimit] processors, -1 is unlimited.");
bool fGenerate = true;
if (params.size() > 0)
fGenerate = params[0].get_bool();
if (params.size() > 1)
{
int nGenProcLimit = params[1].get_int();
fLimitProcessors = (nGenProcLimit != -1);
CWalletDB().WriteSetting("fLimitProcessors", fLimitProcessors);
if (nGenProcLimit != -1)
CWalletDB().WriteSetting("nLimitProcessors", nLimitProcessors = nGenProcLimit);
}
GenerateBitcoins(fGenerate);
return Value::null;
}
Value getinfo(const Array& params)
{
if (params.size() != 0)
throw runtime_error(
"getinfo (no parameters)");
Object obj;
obj.push_back(Pair("balance", (double)GetBalance() / (double)COIN));
obj.push_back(Pair("blocks", (int)nBestHeight + 1));
obj.push_back(Pair("connections", (int)vNodes.size()));
obj.push_back(Pair("proxy", (fUseProxy ? addrProxy.ToStringIPPort() : string())));
obj.push_back(Pair("generate", (bool)fGenerateBitcoins));
obj.push_back(Pair("genproclimit", (int)(fLimitProcessors ? nLimitProcessors : -1)));
return obj;
}
Value getnewaddress(const Array& params) Value getnewaddress(const Array& params)
{ {
if (params.size() > 1) if (params.size() > 1)
@ -102,7 +178,6 @@ Value getnewaddress(const Array& params)
// Generate a new key that is added to wallet // Generate a new key that is added to wallet
string strAddress = PubKeyToAddress(GenerateNewKey()); string strAddress = PubKeyToAddress(GenerateNewKey());
if (params.size() > 0)
SetAddressBookName(strAddress, strLabel); SetAddressBookName(strAddress, strLabel);
return strAddress; return strAddress;
} }
@ -214,10 +289,10 @@ Value getallreceived(const Array& params)
"getallreceived [minconf=1]\n" "getallreceived [minconf=1]\n"
"[minconf] is the minimum number of confirmations before payments are included.\n" "[minconf] is the minimum number of confirmations before payments are included.\n"
"Returns an array of objects containing:\n" "Returns an array of objects containing:\n"
" \"address\" : bitcoin address\n" " \"address\" : receiving address\n"
" \"amount\" : total amount received by the address\n" " \"amount\" : total amount received by the address\n"
" \"conf\" : number of confirmations\n" " \"confirmations\" : number of confirmations of the most recent transaction included\n"
" \"label\" : the label set for this address when it was created by getnewaddress"); " \"label\" : the label of the receiving address");
// Minimum confirmations // Minimum confirmations
int nMinDepth = 1; int nMinDepth = 1;
@ -235,8 +310,17 @@ Value getallreceived(const Array& params)
continue; continue;
int nDepth = wtx.GetDepthInMainChain(); int nDepth = wtx.GetDepthInMainChain();
if (nDepth >= nMinDepth) if (nDepth < nMinDepth)
{ continue;
// Filter out debits and payments to self, which may have change return
// we don't want to count.
int64 nCredit = wtx.GetCredit(true);
int64 nDebit = wtx.GetDebit();
int64 nNet = nCredit - nDebit;
if (nNet <= 0)
continue;
foreach(const CTxOut& txout, wtx.vout) foreach(const CTxOut& txout, wtx.vout)
{ {
uint160 hash160 = txout.scriptPubKey.GetBitcoinAddressHash160(); uint160 hash160 = txout.scriptPubKey.GetBitcoinAddressHash160();
@ -249,7 +333,6 @@ Value getallreceived(const Array& params)
} }
} }
} }
}
// Reply // Reply
Array ret; Array ret;
@ -266,7 +349,7 @@ Value getallreceived(const Array& params)
Object obj; Object obj;
obj.push_back(Pair("address", strAddress)); obj.push_back(Pair("address", strAddress));
obj.push_back(Pair("amount", (double)(*it).second.nAmount / (double)COIN)); obj.push_back(Pair("amount", (double)(*it).second.nAmount / (double)COIN));
obj.push_back(Pair("conf", (*it).second.nConf)); obj.push_back(Pair("confirmations", (*it).second.nConf));
obj.push_back(Pair("label", strLabel)); obj.push_back(Pair("label", strLabel));
ret.push_back(obj); ret.push_back(obj);
} }
@ -290,7 +373,12 @@ pair<string, rpcfn_type> pCallTable[] =
make_pair("stop", &stop), make_pair("stop", &stop),
make_pair("getblockcount", &getblockcount), make_pair("getblockcount", &getblockcount),
make_pair("getblocknumber", &getblocknumber), make_pair("getblocknumber", &getblocknumber),
make_pair("getconnectioncount", &getconnectioncount),
make_pair("getdifficulty", &getdifficulty), make_pair("getdifficulty", &getdifficulty),
make_pair("getbalance", &getbalance),
make_pair("getgenerate", &getgenerate),
make_pair("setgenerate", &setgenerate),
make_pair("getinfo", &getinfo),
make_pair("getnewaddress", &getnewaddress), make_pair("getnewaddress", &getnewaddress),
make_pair("sendtoaddress", &sendtoaddress), make_pair("sendtoaddress", &sendtoaddress),
make_pair("listtransactions", &listtransactions), make_pair("listtransactions", &listtransactions),
@ -568,9 +656,13 @@ int CommandLineRPC(int argc, char *argv[])
Array params; Array params;
for (int i = 2; i < argc; i++) for (int i = 2; i < argc; i++)
params.push_back(argv[i]); params.push_back(argv[i]);
int n = params.size();
//
// Special case other types // Special case other types
int n = params.size(); //
if (strMethod == "setgenerate" && n > 0) ConvertTo<bool>(params[0]);
if (strMethod == "setgenerate" && n > 1) ConvertTo<boost::int64_t>(params[1]);
if (strMethod == "sendtoaddress" && n > 1) ConvertTo<double>(params[1]); if (strMethod == "sendtoaddress" && n > 1) ConvertTo<double>(params[1]);
if (strMethod == "listtransactions" && n > 0) ConvertTo<boost::int64_t>(params[0]); if (strMethod == "listtransactions" && n > 0) ConvertTo<boost::int64_t>(params[0]);
if (strMethod == "listtransactions" && n > 1) ConvertTo<bool>(params[1]); if (strMethod == "listtransactions" && n > 1) ConvertTo<bool>(params[1]);

2
serialize.h

@ -19,7 +19,7 @@ class CScript;
class CDataStream; class CDataStream;
class CAutoFile; class CAutoFile;
static const int VERSION = 205; static const int VERSION = 206;
static const char* pszSubVer = ".0"; static const char* pszSubVer = ".0";

94
ui.cpp

@ -26,6 +26,20 @@ int fMinimizeOnClose = true;
int MyMessageBox(const wxString& message, const wxString& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1)
{
if (fDaemon)
{
printf("wxMessageBox %s: %s\n", string(caption).c_str(), string(message).c_str());
fprintf(stderr, "%s: %s\n", string(caption).c_str(), string(message).c_str());
return wxOK;
}
return wxMessageBox(message, caption, style, parent, x, y);
}
#define wxMessageBox MyMessageBox
@ -209,16 +223,10 @@ 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) int ThreadSafeMessageBox(const string& message, const string& caption, int style, wxWindow* parent, int x, int y)
{ {
if (fDaemon)
{
printf("wxMessageBox %s: %s\n", caption.c_str(), message.c_str());
return wxOK;
}
#ifdef __WXMSW__ #ifdef __WXMSW__
return wxMessageBox(message, caption, style, parent, x, y); return wxMessageBox(message, caption, style, parent, x, y);
#else #else
if (wxThread::IsMain()) if (wxThread::IsMain() || fDaemon)
{ {
return wxMessageBox(message, caption, style, parent, x, y); return wxMessageBox(message, caption, style, parent, x, y);
} }
@ -563,7 +571,7 @@ string SingleLine(const string& strIn)
bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex)
{ {
int64 nTime = wtx.nTimeDisplayed = wtx.GetTxTime(); int64 nTime = wtx.nTimeDisplayed = wtx.GetTxTime();
int64 nCredit = wtx.GetCredit(); int64 nCredit = wtx.GetCredit(true);
int64 nDebit = wtx.GetDebit(); int64 nDebit = wtx.GetDebit();
int64 nNet = nCredit - nDebit; int64 nNet = nCredit - nDebit;
uint256 hash = wtx.GetHash(); uint256 hash = wtx.GetHash();
@ -2571,6 +2579,9 @@ public:
bool OnInit2(); bool OnInit2();
int OnExit(); int OnExit();
// Hook Initialize so we can start without GUI
virtual bool Initialize(int& argc, wxChar** argv);
// 2nd-level exception handling: we get all the exceptions occurring in any // 2nd-level exception handling: we get all the exceptions occurring in any
// event handler here // event handler here
virtual bool OnExceptionInMainLoop(); virtual bool OnExceptionInMainLoop();
@ -2586,6 +2597,64 @@ public:
IMPLEMENT_APP(CMyApp) IMPLEMENT_APP(CMyApp)
bool CMyApp::Initialize(int& argc, wxChar** argv)
{
if (argc > 1 && argv[1][0] != '-' && (!fWindows || argv[1][0] != '/') &&
wxString(argv[1]) != "start")
{
fCommandLine = true;
}
else
{
// wxApp::Initialize will remove environment-specific parameters,
// so it's too early to call ParseParameters yet
for (int i = 1; i < argc; i++)
{
wxString str = argv[i];
#ifdef __WXMSW__
if (str.size() >= 1 && str[0] == '/')
str[0] = '-';
str = str.MakeLower();
#endif
// haven't decided which argument to use for this yet
if (str == "-daemon" || str == "-d" || str == "start")
fDaemon = true;
}
}
#ifdef __WXGTK__
if (fDaemon || fCommandLine)
{
// Call the original Initialize while suppressing error messages
// and ignoring failure. If unable to initialize GTK, it fails
// near the end so hopefully the last few things don't matter.
{
wxLogNull logNo;
wxApp::Initialize(argc, argv);
}
if (fDaemon)
{
fprintf(stdout, "bitcoin server starting\n");
// Daemonize
pid_t pid = fork();
if (pid < 0)
{
fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno);
return false;
}
if (pid > 0)
pthread_exit((void*)0);
}
return true;
}
#endif
return wxApp::Initialize(argc, argv);
}
bool CMyApp::OnInit() bool CMyApp::OnInit()
{ {
bool fRet = false; bool fRet = false;
@ -2650,7 +2719,7 @@ bool CMyApp::OnInit2()
// //
// Parameters // Parameters
// //
if (argc > 1 && argv[1][0] != '-' && argv[1][0] != '/') if (fCommandLine)
{ {
int ret = CommandLineRPC(argc, argv); int ret = CommandLineRPC(argc, argv);
exit(ret); exit(ret);
@ -2696,13 +2765,6 @@ bool CMyApp::OnInit2()
if (mapArgs.count("-printtodebugger")) if (mapArgs.count("-printtodebugger"))
fPrintToDebugger = true; 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]) if (!fDebug && !pszSetDataDir[0])
ShrinkDebugFile(); ShrinkDebugFile();
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");

4
util.cpp

@ -13,6 +13,7 @@ bool fPrintToDebugger = false;
char pszSetDataDir[MAX_PATH] = ""; char pszSetDataDir[MAX_PATH] = "";
bool fShutdown = false; bool fShutdown = false;
bool fDaemon = false; bool fDaemon = false;
bool fCommandLine = false;
@ -500,7 +501,8 @@ void PrintException(std::exception* pex, const char* pszThread)
char pszMessage[1000]; char pszMessage[1000];
FormatException(pszMessage, pex, pszThread); FormatException(pszMessage, pex, pszThread);
printf("\n\n************************\n%s\n", pszMessage); printf("\n\n************************\n%s\n", pszMessage);
if (wxTheApp) fprintf(stderr, "\n\n************************\n%s\n", pszMessage);
if (wxTheApp && !fDaemon)
wxMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR); wxMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR);
throw; throw;
//DebugBreak(); //DebugBreak();

1
util.h

@ -121,6 +121,7 @@ extern bool fPrintToDebugger;
extern char pszSetDataDir[MAX_PATH]; extern char pszSetDataDir[MAX_PATH];
extern bool fShutdown; extern bool fShutdown;
extern bool fDaemon; extern bool fDaemon;
extern bool fCommandLine;
void RandAddSeed(); void RandAddSeed();
void RandAddSeedPerfmon(); void RandAddSeedPerfmon();

Loading…
Cancel
Save