Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Execute a command when best block changes (-blocknotify=<cmd>) #714

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ bool AppInit2(int argc, char* argv[])
" -rpcport=<port> \t\t " + _("Listen for JSON-RPC connections on <port> (default: 8332)") + "\n" +
" -rpcallowip=<ip> \t\t " + _("Allow JSON-RPC connections from specified IP address") + "\n" +
" -rpcconnect=<ip> \t " + _("Send commands to node running on <ip> (default: 127.0.0.1)") + "\n" +
" -blocknotify=<cmd> " + _("Execute this command when the best block changes") + "\n" +
" -keypool=<n> \t " + _("Set key pool size to <n> (default: 100)") + "\n" +
" -rescan \t " + _("Rescan the block chain for missing wallet transactions") + "\n";

Expand Down
76 changes: 75 additions & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@
// Copyright (c) 2011 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.

#ifdef WIN32
#include <winbase.h>
#else
#include <errno.h>
#endif
#include <stdio.h>
#include <string.h>
#ifndef WIN32
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#endif

#include "headers.h"
#include "checkpoints.h"
#include "db.h"
Expand Down Expand Up @@ -1189,7 +1203,8 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew)
}

// Update best block in wallet (so we can detect restored wallets)
if (!IsInitialBlockDownload())
bool fInitialDownload = IsInitialBlockDownload();
if (!fInitialDownload)
{
const CBlockLocator locator(pindexNew);
::SetBestChain(locator);
Expand All @@ -1204,6 +1219,65 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew)
nTransactionsUpdated++;
printf("SetBestChain: new best=%s height=%d work=%s\n", hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, bnBestChainWork.ToString().c_str());

if (!fInitialDownload)
{
// Support block notification
std::string strCmd = GetArg("-blocknotify", "");
if (!strCmd.empty())
{
#ifndef WIN32
fflush(stdout);
pid_t nPid = fork();
if (!nPid)
{
if ((nPid = fork()) != 0)
// middle
_Exit(nPid < 0);
// child
#endif
try
{
std::string::size_type nPos;
while ((nPos = strCmd.find("%s")) != std::string::npos)
strCmd.replace(nPos, 2, hash.GetHex());
#ifndef WIN32
}
catch (...)
{
printf("BlockNotify: Exception preparing command\n");
fflush(stdout);
_exit(1);
}
execl("/bin/sh", "/bin/sh", "-c", strCmd.c_str(), NULL);
printf("BlockNotify: Failed to exec: %s\n", strerror(errno));
fflush(stdout);
_exit(2);
}
else
if (nPid == -1)
printf("BlockNotify: Failed to fork: %s\n", strerror(errno));
else
waitpid(nPid, NULL, 0);
#else
// inside the 'try' block...
STARTUPINFO si;
PROCESS_INFORMATION pi;

memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
memset(&pi, 0, sizeof(pi));

if (!CreateProcess(NULL, strCmd.c_str(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
printf("BlockNotify: CreateProcess failed (%d)\n", GetLastError());
}
catch (...)
{
printf("BlockNotify: Error occurred\n");
}
#endif
}
}

return true;
}

Expand Down