Yeah, don't do that unless you are sure that your transaction volume will be extremely low.
You want the process run by -walletnotify to be very fast. Ideally, it should spit out a line into a pipe (or file or socket) and end promptly.
You should then have a different process, either a daemon or a cron job, read that stream and gather whatever information you need. You should be checking the confirmation count of the transactions, not the balance of the account. For that matter, using accounts can get you into trouble. Make sure you know what you are doing if you are going to use them at all.
-walletnotify will trigger when a transaction is included in a block, but it might also trigger if the transaction shows up over the network as a loose transaction. So, you should check the confirmation count each time -walletnotify hits, until you see at least one confirmation. After that, you should check it every time you see a block to make sure the count has reached your threshold. You could optimize that a bit by skipping the slow RPC calls until number of blocks have been seen after the transaction was first included.
To be honest when I read your comment a few hours ago I had no clue what a pipeline, socket and cron job was, but after much googling, coffee and Wu Tang later I have come up with something like this.
walletnotify=/home/btcdev/walletnotifyclient 127.0.0.1 1337 %s
walletnotifyclient.c#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char *argv[])
{
if (argc < 4) {
printf("\n Usage: %s \n",argv[0]);
exit(0);
}
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[256];
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
fprintf(stderr,"ERROR, opening socket\n");
exit(0);
}
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) {
fprintf(stderr,"ERROR, connecting\n");
exit(0);
}
snprintf(buffer, sizeof(buffer), "%s",argv[3]);
n = write(sockfd, buffer, strlen(buffer));
if (n < 0) {
fprintf(stderr,"ERROR, writing to socket\n");
exit(0);
}
close(sockfd);
return 0;
exit(0);
}
Server,phpinclude 'bitcoin_lib.php';
$bitcoin = new bitcoin('http://user:pass@127.0.0.1:8332/');
$txid = array(
'unconfirmed' => array(),
'confirmed' => array()
);
$currentBlock = 0; //the current block
$minConfirmation = 3; //minimum tansaction confirmations
$blockThreshold = 3; //blocks to wait checking transaction for confirmations
$server = stream_socket_server("tcp://127.0.0.1:1337", $errno, $errorMessage);
if ($server === false) {
throw new UnexpectedValueException("Could not bind to socket: $errorMessage");
}
for (;;) {
$client = @stream_socket_accept($server);
if ($client) {
$message = stream_get_contents($client);
if (strlen($message) == 64) { //recived a TXID
echo 'New tx:'.$message."\n";
$txid['unconfirmed'][] = array(
'onBlock' => $currentBlock + $blockThreshold,
'txid' => $message
);
}
else { //recived the current block
$currentBlock = $bitcoin->getblockcount();
echo 'New Block:'.$currentBlock."\n";
//loop through unconfirmed transactions on new block
foreach ($txid['unconfirmed'] as $key => $unconfirmedTX) {
if($currentBlock >= $unconfirmedTX['onBlock']) {
echo $unconfirmedTX['txid'].' : reached blockThreshold'."\n";
$gettransaction = $bitcoin->gettransaction($unconfirmedTX['txid']);
if($gettransaction['confirmations'] >= $minConfirmation) { //transaction has been confirmed
echo $unconfirmedTX['txid'].' : confirmed'."\n";
unset($txid['unconfirmed'][$key]);
$txid['confirmed'][] = $gettransaction;
}
else { //Transaction does not have min confirmations
echo $unconfirmedTX['txid'].' : unconfirmed wait '.$unconfirmedTX['confirmations'].' blocks'."\n";
$blockstowait = $minConfirmation - $unconfirmedTX['confirmations']; //set blocks to wait before rechecking transaction
$gettransaction['onBlock'] = $currentBlock + $blockstowait;
$txid['unconfirmed'][$key] = $gettransaction;
}
}
else {
$blockstowait = $unconfirmedTX['onBlock'] - $currentBlock;
echo $unconfirmedTX['txid'].' : has not reached blockThreshold, wait '.$blockstowait.' blocks'."\n";
}
}
}
fclose($client);
}
}
?>
Am I on the right track or have I gone crazy?