@@ -686,8 +686,72 @@ static struct command_result *getutxout(struct command *cmd,
686686 return command_still_pending (cmd );
687687}
688688
689+ static void bitcoind_failure (struct plugin * p , const char * error_message )
690+ {
691+ const char * * cmd = gather_args (bitcoind , "echo" , NULL );
692+ const char * err =
693+ tal_fmt (bitcoind , "\n%s\n\n"
694+ "Make sure you have bitcoind running and that bitcoin-cli"
695+ " is able to connect to bitcoind.\n\n"
696+ "You can verify that your Bitcoin Core installation is"
697+ " ready for use by running:\n\n"
698+ " $ %s 'hello world'\n" , error_message ,
699+ args_string (cmd , cmd ));
700+ plugin_err (p , err );
701+ }
702+
703+ static void wait_for_bitcoind (struct plugin * p )
704+ {
705+ int from , status , ret ;
706+ pid_t child ;
707+ const char * * cmd = gather_args (bitcoind , "echo" , NULL );
708+ bool printed = false;
709+
710+ for (;;) {
711+ child = pipecmdarr (NULL , & from , & from , cast_const2 (char * * ,cmd ));
712+ if (child < 0 ) {
713+ if (errno == ENOENT )
714+ bitcoind_failure (p , "bitcoin-cli not found. Is bitcoin-cli "
715+ "(part of Bitcoin Core) available in your PATH?" );
716+ plugin_err (p , "%s exec failed: %s" , cmd [0 ], strerror (errno ));
717+ }
718+
719+ char * output = grab_fd (cmd , from );
720+
721+ while ((ret = waitpid (child , & status , 0 )) < 0 && errno == EINTR );
722+ if (ret != child )
723+ bitcoind_failure (p , tal_fmt (bitcoind , "Waiting for %s: %s" ,
724+ cmd [0 ], strerror (errno )));
725+ if (!WIFEXITED (status ))
726+ bitcoind_failure (p , tal_fmt (bitcoind , "Death of %s: signal %i" ,
727+ cmd [0 ], WTERMSIG (status )));
728+
729+ if (WEXITSTATUS (status ) == 0 )
730+ break ;
731+
732+ /* bitcoin/src/rpc/protocol.h:
733+ * RPC_IN_WARMUP = -28, //!< Client still warming up
734+ */
735+ if (WEXITSTATUS (status ) != 28 ) {
736+ if (WEXITSTATUS (status ) == 1 )
737+ bitcoind_failure (p , "Could not connect to bitcoind using"
738+ " bitcoin-cli. Is bitcoind running?" );
739+ bitcoind_failure (p , tal_fmt (bitcoind , "%s exited with code %i: %s" ,
740+ cmd [0 ], WEXITSTATUS (status ), output ));
741+ }
742+
743+ if (!printed ) {
744+ plugin_log (p , LOG_UNUSUAL ,
745+ "Waiting for bitcoind to warm up..." );
746+ printed = true;
747+ }
748+ sleep (1 );
749+ }
750+ tal_free (cmd );
751+ }
752+
689753/* Initialize the global context when handshake is done. */
690- static void init (struct plugin * p UNUSED , const char * buffer UNUSED ,
754+ static void init (struct plugin * p , const char * buffer UNUSED ,
691755 const jsmntok_t * config UNUSED )
692756{
693757 bitcoind = tal (NULL , struct bitcoind );
@@ -704,6 +768,10 @@ static void init(struct plugin *p UNUSED, const char *buffer UNUSED,
704768 bitcoind -> rpcpass = NULL ;
705769 bitcoind -> rpcconnect = NULL ;
706770 bitcoind -> rpcport = NULL ;
771+
772+ wait_for_bitcoind (p );
773+ plugin_log (p , LOG_INFORM ,
774+ "bitcoin-cli initialized and connected to bitcoind." );
707775}
708776
709777static const struct plugin_command commands [] = {
0 commit comments