-
Notifications
You must be signed in to change notification settings - Fork 19
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
reporter: setup zmq block subscription #92
Conversation
8c372ab
to
5afdeec
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for figuring out all the ZMQ stuff, which looks challenging! Left some comments on the overall design.
sample-vigilante.yml
Outdated
no-client-tls: true | ||
ca-file: $TESTNET_PATH/bitcoin/rpc.cert | ||
endpoint: localhost:18556 | ||
endpoint: localhost:18443 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we change these parameters?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is the port required for bitcoind regtest
sample-vigilante.yml
Outdated
tx-fee: 2500 | ||
wallet-endpoint: localhost:18554 | ||
wallet-password: walletpass | ||
wallet-name: default | ||
wallet-lock-time: 10 | ||
wallet-ca-file: $TESTNET_PATH/bitcoin/rpc-wallet.cert | ||
net-params: simnet | ||
net-params: regtest |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe worth adding some comments about the supported net parameters of Btcd and bitcoind.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
types/blockevent.go
Outdated
|
||
TransactionRemoved | ||
|
||
TransactionAdded |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we interested in these events?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nope, we are not using it anywhere, I added it because these are returned from the sequence socket.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then I would say we ignore these events, since they are not related to blocks while our event type is called BlockEvent
.
HTTPPostMode: true, | ||
User: cfg.Username, | ||
Pass: cfg.Password, | ||
DisableTLS: cfg.DisableClientTLS, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this because bitcoind
does not support TLS?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right, it doesn't support TLS.
btcclient/client_block_subscriber.go
Outdated
panic(err) | ||
} | ||
|
||
c.ZmqSequenceMsgChan = ch |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we filter BlockConnected
and BlockDisconnected
events from ZmqSequenceMsgChan
, and forward these events to BlockEventChan
in a goroutine, so that we can omit the public ZmqSequenceMsgChan
channel in Client
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think in that case ZmqSequenceMsgChan
would still need to be a public channel as we process events in different package here ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we use a unified channel, then the two different handlers can be merged, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, so I think you mean we don't need ZmqSequenceMsgChan
, we should directly push messages to BlockEventChan
from zmq library here. Yes that can be done 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, I feel like this can simplify the design a little bit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was refraining to use bbn/vigilante code inside zmq package as I wanted to keep it separate but I agree above suggestion will simplify stuff, will fix it soon.
Note
As the zmq socket just gives us block hash, to make the
BlockEvent
, I will need to fetch header/height using rpc client , so need to pass rpc client info in the zmq lib as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, for modularity I think we can make events like TransactionRemoved
and ZmqSequenceMsgChan
to be a part of this Zmq library, while making BTC client to only consume block-related events.
config/bitcoin.go
Outdated
@@ -32,6 +35,17 @@ func (cfg *BTCConfig) Validate() error { | |||
if _, ok := types.GetValidNetParams()[cfg.NetParams]; !ok { | |||
return errors.New("invalid net params") | |||
} | |||
|
|||
if cfg.EnableZmq { | |||
if cfg.ZmqPubAddress == "" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably a TODO on regex check of IP address
reporter/block_handler.go
Outdated
func (r *Reporter) blockEventHandler() { | ||
defer r.wg.Done() | ||
quit := r.quitChan() | ||
|
||
for { | ||
select { | ||
case event := <-r.btcClient.BlockEventChan: | ||
case event, open := <-r.btcClient.BlockEventChan: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
reporter/block_handler.go
Outdated
@@ -23,6 +31,56 @@ func (r *Reporter) blockEventHandler() { | |||
} | |||
} | |||
|
|||
// zmqSequenceMessageHandler handles sequence messages from the ZMQ sequence socket. | |||
func (r *Reporter) zmqSequenceMessageHandler() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be replaced by the redirection approach suggested above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done.
@@ -0,0 +1,115 @@ | |||
package zmq |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work on the ZMQ library, which is a tough one! Since only btcclient
will use this zmq
library, can we move zmq/
to btcclient/zmq
? In addition, IIRC some of the code is from an open-source codebase, so perhaps we can attach URL on the origin of these code here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added a reference to open source code at start of the package but couldn't move zmq
inside btcclient
due to cyclic import issues.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perfect, thanks for figuring these Zmq things out!
} | ||
if backend != rpcclient.Btcd { | ||
return nil, fmt.Errorf("NewWithBlockSubscriber is only compatible with Btcd") | ||
// ensure we are using bitcoind as Bitcoin node, as zmq is only supported by bitcoind |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These checks between L50-L56 can happen before L45, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
c.blockEventChan <- types.NewBlockEvent(event, ib.Height, ib.Header) | ||
} | ||
|
||
func (c *Client) getBlockByHash(blockHash *chainhash.Hash) (*types.IndexedBlock, *wire.MsgBlock, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function looks like the cause why the Zmq client needs the pointer to the BTC client. It would be good if we avoid them referencing each other. Is it possible to
- remove the height from
BlockEvent
and remove this function and the pointer to the BTC client, or - pass
BlockEvent
with zero height when using Zmq?
since the height in BlockEvent
is not used anyway. This also might allow us to put zmq
/ under btcclient/
as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ZMQ only needs BTC client to query BTC. Instead pointing to BTC client , I inserted rpc client inside zmq client so it can query directly here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in this PR I inserted rpc client in the zmq client here
I was asking the possibility to avoid the zmq client to query BTC client. There might be some dependency issues when BTC client and Zmq client are referencing each other. From a modularity point of view the Zmq client should not refer to BTC client as well. The ideal case would be that Zmq client pushes messages to the BlockEvent channel without querying BTC client.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ideal case would be that Zmq client pushes messages to the BlockEvent channel without querying BTC client.
Sure this is possible.
Is it possible to
- remove the height from BlockEvent and remove this function and the pointer to the BTC client, or
- pass BlockEvent with zero height when using Zmq?
I think this might not be work as zmq socket just provides block hash, it doesn't give us header or height so omitting height won't be suffice. We should rather change BlockEvent
to accept just hash as both bitcoind and btcd provides hash on notification arrival. We can then query BTC when this block is handled in blockEventHandler
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added TODO for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I would also prefer removing the height from BlockEvent
. Let's do it in subsequent PRs. 👍
Co-authored-by: Runchao Han <[email protected]>
815f460
to
d53144e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work! Minor comments
HTTPPostMode: true, | ||
User: cfg.Username, | ||
Pass: cfg.Password, | ||
DisableTLS: cfg.DisableClientTLS, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When bitcoind is used, DisableClientTLS
should always be true
, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup, will fix it in next PR.
if err != nil { | ||
return nil, fmt.Errorf("failed to get BTC backend: %v", err) | ||
} | ||
if backend != rpcclient.BitcoindPost19 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is BitcoindPost19
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are enums given by the rpc client library
BTCD
is used for btcdBitcoindPost19
is used for bitcoind
Check here
case types.WebsocketMode: | ||
notificationHandlers := rpcclient.NotificationHandlers{ | ||
OnFilteredBlockConnected: func(height int32, header *wire.BlockHeader, txs []*btcutil.Tx) { | ||
log.Debugf("Block %v at height %d has been connected at time %v", header.BlockHash(), height, header.Timestamp) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These debugging logs only appear on a btcd connection. To be more consistent, maybe we could add those in the consumer channel?
WalletName string `mapstructure:"wallet-name"` | ||
WalletCAFile string `mapstructure:"wallet-ca-file"` | ||
WalletLockTime int64 `mapstructure:"wallet-lock-time"` // time duration in which the wallet remains unlocked, in seconds | ||
TxFee btcutil.Amount `mapstructure:"tx-fee"` // BTC tx fee, in BTC |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is in Satoshi
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right, I will fix it in the next PR.
Fixes
https://babylon-chain.atlassian.net/browse/BM-208
Description
This PR adds zmq-based block subscription support in the reporter.
Setup
bitcoin-cli getzmqnotifications
in terminal to confirm if notifications are enabledbitcoin-cli -generate 1