Support connecting to bitcoind via ZMQ (#286)

* add ZMQ env vars

* consolidate config and app-config naming
This commit is contained in:
Marco Argentieri
2024-11-18 18:49:00 +01:00
committed by GitHub
parent acb54436dd
commit 6ed4e30b6d
5 changed files with 79 additions and 7 deletions

View File

@@ -44,6 +44,8 @@ run: clean
export ARK_BITCOIND_RPC_USER=admin1; \
export ARK_BITCOIND_RPC_PASS=123; \
export ARK_BITCOIND_RPC_HOST=localhost:18443; \
export ARK_BITCOIND_ZMQ_BLOCK=tcp://127.0.0.1:28332; \
export ARK_BITCOIND_ZMQ_TX=tcp://127.0.0.1:28333; \
export ARK_DATADIR=./data/regtest; \
go run ./cmd/arkd

View File

@@ -77,6 +77,8 @@ func mainAction(_ *cli.Context) error {
BitcoindRpcUser: cfg.BitcoindRpcUser,
BitcoindRpcPass: cfg.BitcoindRpcPass,
BitcoindRpcHost: cfg.BitcoindRpcHost,
BitcoindZMQBlock: cfg.BitcoindZMQBlock,
BitcoindZMQTx: cfg.BitcoindZMQTx,
BoardingExitDelay: cfg.BoardingExitDelay,
UnlockerType: cfg.UnlockerType,
UnlockerFilePath: cfg.UnlockerFilePath,

View File

@@ -70,11 +70,13 @@ type Config struct {
NostrDefaultRelays []string
NoteUriPrefix string
EsploraURL string
NeutrinoPeer string
BitcoindRpcUser string
BitcoindRpcPass string
BitcoindRpcHost string
EsploraURL string
NeutrinoPeer string
BitcoindRpcUser string
BitcoindRpcPass string
BitcoindRpcHost string
BitcoindZMQBlock string
BitcoindZMQTx string
UnlockerType string
UnlockerFilePath string // file unlocker
@@ -271,12 +273,16 @@ func (c *Config) walletService() error {
var err error
switch {
case c.BitcoindZMQBlock != "" && c.BitcoindZMQTx != "" && c.BitcoindRpcUser != "" && c.BitcoindRpcPass != "":
svc, err = btcwallet.NewService(btcwallet.WalletConfig{
Datadir: c.DbDir,
Network: c.Network,
}, btcwallet.WithBitcoindZMQ(c.BitcoindZMQBlock, c.BitcoindZMQTx, c.BitcoindRpcHost, c.BitcoindRpcUser, c.BitcoindRpcPass))
case c.BitcoindRpcUser != "" && c.BitcoindRpcPass != "":
svc, err = btcwallet.NewService(btcwallet.WalletConfig{
Datadir: c.DbDir,
Network: c.Network,
}, btcwallet.WithPollingBitcoind(c.BitcoindRpcHost, c.BitcoindRpcUser, c.BitcoindRpcPass))
default:
// Default to Neutrino for Bitcoin mainnet or when NeutrinoPeer is explicitly set
if len(c.EsploraURL) == 0 {

View File

@@ -33,6 +33,8 @@ type Config struct {
BitcoindRpcUser string
BitcoindRpcPass string
BitcoindRpcHost string
BitcoindZMQBlock string
BitcoindZMQTx string
TLSExtraIPs []string
TLSExtraDomains []string
UnlockerType string
@@ -65,6 +67,8 @@ var (
// #nosec G101
BitcoindRpcPass = "BITCOIND_RPC_PASS"
BitcoindRpcHost = "BITCOIND_RPC_HOST"
BitcoindZMQBlock = "BITCOIND_ZMQ_BLOCK"
BitcoindZMQTx = "BITCOIND_ZMQ_TX"
NoMacaroons = "NO_MACAROONS"
NoTLS = "NO_TLS"
TLSExtraIP = "TLS_EXTRA_IP"
@@ -145,6 +149,8 @@ func LoadConfig() (*Config, error) {
BitcoindRpcUser: viper.GetString(BitcoindRpcUser),
BitcoindRpcPass: viper.GetString(BitcoindRpcPass),
BitcoindRpcHost: viper.GetString(BitcoindRpcHost),
BitcoindZMQBlock: viper.GetString(BitcoindZMQBlock),
BitcoindZMQTx: viper.GetString(BitcoindZMQTx),
NoMacaroons: viper.GetBool(NoMacaroons),
TLSExtraIPs: viper.GetStringSlice(TLSExtraIP),
TLSExtraDomains: viper.GetStringSlice(TLSExtraDomain),

View File

@@ -193,7 +193,7 @@ func WithPollingBitcoind(host, user, pass string) WalletOption {
},
}
chain.UseLogger(logger("chain"))
btcwallet.UseLogger(logger("btcwallet"))
// Create the BitcoindConn first
bitcoindConn, err := chain.NewBitcoindConn(bitcoindConfig)
@@ -258,6 +258,62 @@ func WithPollingBitcoind(host, user, pass string) WalletOption {
}
}
func WithBitcoindZMQ(block, tx string, host, user, pass string) WalletOption {
return func(s *service) error {
if s.chainSource != nil {
return fmt.Errorf("chain source already set")
}
bitcoindConfig := &chain.BitcoindConfig{
ChainParams: s.cfg.chainParams(),
Host: host,
User: user,
Pass: pass,
ZMQConfig: &chain.ZMQConfig{
ZMQBlockHost: block,
ZMQTxHost: tx,
ZMQReadDeadline: 5 * time.Second,
},
}
btcwallet.UseLogger(logger("btcwallet"))
bitcoindConn, err := chain.NewBitcoindConn(bitcoindConfig)
if err != nil {
return fmt.Errorf("failed to create bitcoind connection: %w", err)
}
if err := bitcoindConn.Start(); err != nil {
return fmt.Errorf("failed to start bitcoind connection: %w", err)
}
chainClient := bitcoindConn.NewBitcoindClient()
if err := chainClient.Start(); err != nil {
bitcoindConn.Stop()
return fmt.Errorf("failed to start bitcoind client: %w", err)
}
for !chainClient.IsCurrent() {
time.Sleep(1 * time.Second)
}
if err := withChainSource(chainClient)(s); err != nil {
chainClient.Stop()
bitcoindConn.Stop()
return fmt.Errorf("failed to set chain source: %w", err)
}
if err := withScanner(chainClient)(s); err != nil {
chainClient.Stop()
bitcoindConn.Stop()
return fmt.Errorf("failed to set scanner: %w", err)
}
return nil
}
}
// NewService creates the wallet service, an option must be set to configure the chain source.
func NewService(cfg WalletConfig, options ...WalletOption) (ports.WalletService, error) {
wallet.UseLogger(logger("wallet"))