informalsystems / tendermint-rs

Client libraries for Tendermint/CometBFT in Rust!
Apache License 2.0
608 stars 224 forks source link

generate privval gRPC server and provide a high-level pluggable default implementation #1134

Open tomtau opened 2 years ago

tomtau commented 2 years ago

Version(s) of tendermint-rs: v0.24.0-pre.2

Description

"privval" is an interface used by a Tendermint process (on validator nodes) to communicate with a signing backend (e.g. YubiHSM). Previously, "privval" was over a custom socket protocol (implemented e.g. in tmkms) that leveraged Unix domain sockets or Tendermint P2P over TCP where Tendermint acted as a server, and a signing backend connected to it as a client. In Tendermint 0.35, a new method for "privval" was introduced: the signer is a standard gRPC server/service, and Tendermint connects to it as a client. In Tendermint 0.36, we expect the old "privval" custom socket protocol will be removed and only the gRPC-based "privval" interface will be provided.

Given these circumstances, I think it makes sense for tendermint-rs to support this interface via the following features:

  1. provide a "raw" service API definition by enabling build_server(true) in tonic_build, probably via a feature-flag (as not every usage of tendermint-proto needs it)
  2. provide a high-level wrapper over the raw service (likely in a new "tendermint-validator" crate) which should do the following:

Here's a sketch of the potential interface:

#[async_trait]
pub trait SignerProvider {
    async fn sign(&self, signable_bytes: &[u8]) -> Result<Signature, Error>;
    async fn load_pubkey(&self) -> Result<PublicKey, Error>;
    async fn load_state(&self) -> Result<consensus::State, Error>;
    async fn persist_state(&mut self, new_state: &consensus::State) -> Result<(), Error>;
}

load_state and persist_state could potentially be in a separate trait, so that one can e.g. have a default file-based state persistence, but different signer backends are free to implement what makes sense in their context (e.g. write to CPU monotonic counters or an external service).

Definition of "done"

Related issues:

tomtau commented 2 years ago

CC @marbar3778 @tony-iqlusion

tony-iqlusion commented 2 years ago

This is definitely something I'm interested in, although there is presently no integration with tonic whatsoever in tendermint-proto, and nearly no gRPC support (aside from this).

adizere commented 1 year ago

The work here depends on https://github.com/cometbft/cometbft/issues/476 right?

tomtau commented 1 year ago

that's right