Skip to content

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

@tomtau

Description

@tomtau

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:
  • provide a basic gRPC server construction options for tonic's Server (e.g. TLS)
  • do basic validation of requests:
  • return a cached public key or request a signature from a signing backend, and return corresponding responses
  • provide a simple interface that can be implemented by different signer backends

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"

  • a feature-flag in tendermint-proto to generate gRPC server definitions (PrivValidatorApi, PrivValidatorApiServer...): tendermint-proto: Add a feature flag and generate gRPC server definitions #1137
  • a new "tendermint-validator" crate that provides a default PrivValidatorApi implementation (validation of types via domain types, basic double signing checking, chain-id verification) with basic common constructors or configurations (e.g. to load the certificates for TLS) and an extensible way to plug in different signer providers (with a software signer given as a sample implementation)

Related issues:

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions