diff --git a/src/chain.rs b/src/chain.rs index a19e4559..166e9f87 100644 --- a/src/chain.rs +++ b/src/chain.rs @@ -23,6 +23,9 @@ pub struct Chain { /// ID of a particular chain pub id: Id, + /// Should extensions for this chain be signed? + pub sign_extensions: bool, + /// Signing keyring for this chain pub keyring: KeyRing, @@ -56,6 +59,7 @@ impl Chain { Ok(Self { id: config.id.clone(), + sign_extensions: config.sign_extensions, keyring: KeyRing::new(config.key_format.clone()), state: Mutex::new(state), }) diff --git a/src/config/chain.rs b/src/config/chain.rs index 37118073..45da49f3 100644 --- a/src/config/chain.rs +++ b/src/config/chain.rs @@ -17,6 +17,16 @@ pub struct ChainConfig { /// Key serialization format configuration for this chain pub key_format: keyring::Format, + /// Should vote extensions on this chain be signed? (default: false) + /// + /// CometBFT v0.38 and newer supports an `ExtendedCommitSig` which requires computing an + /// additional signature over an extension using the consensus key beyond simply signing a vote. + /// + /// Note: in the future this can be autodetected via the `signExtension` field on `SignVote`. + /// See cometbft/cometbft#2439. + #[serde(default)] + pub sign_extensions: bool, + /// Path to chain-specific `priv_validator_state.json` file pub state_file: Option, diff --git a/src/session.rs b/src/session.rs index 59a57617..d61f7831 100644 --- a/src/session.rs +++ b/src/session.rs @@ -150,17 +150,19 @@ impl Session { self.log_signing_request(&signable_msg, started_at).unwrap(); // Add extension signature if the message is a precommit for a non-empty block ID. - if let Some(extension_msg) = signable_msg.extension_bytes(chain_id)? { - let started_at = Instant::now(); - let extension_sig = chain.keyring.sign(public_key, &extension_msg)?; - signable_msg.add_extension_signature(extension_sig)?; - - info!( - "[{}@{}] signed vote extension ({} ms)", - &self.config.chain_id, - &self.config.addr, - started_at.elapsed().as_millis(), - ); + if chain.sign_extensions { + if let Some(extension_msg) = signable_msg.extension_bytes(chain_id)? { + let started_at = Instant::now(); + let extension_sig = chain.keyring.sign(public_key, &extension_msg)?; + signable_msg.add_extension_signature(extension_sig)?; + + info!( + "[{}@{}] signed vote extension ({} ms)", + &self.config.chain_id, + &self.config.addr, + started_at.elapsed().as_millis(), + ); + } } Ok(signable_msg.into()) diff --git a/tmkms.toml.example b/tmkms.toml.example index f285392c..541c6c5f 100644 --- a/tmkms.toml.example +++ b/tmkms.toml.example @@ -16,6 +16,7 @@ [[chain]] id = "cosmoshub-3" key_format = { type = "bech32", account_key_prefix = "cosmospub", consensus_key_prefix = "cosmosvalconspub" } +sign_extensions = false # Should vote extensions for this chain be signed? (default: false) # state_file = "/path/to/cosmoshub_priv_validator_state.json" # state_hook = { cmd = ["/path/to/block/height_script", "--example-arg", "cosmoshub"] }