diff --git a/chain/client/src/client_actor.rs b/chain/client/src/client_actor.rs index 17fa337c51e..bf9d700024f 100644 --- a/chain/client/src/client_actor.rs +++ b/chain/client/src/client_actor.rs @@ -968,15 +968,10 @@ impl ClientActorInner { debug!(target: "client", "Sending announce account for {}", signer.validator_id()); self.last_validator_announce_time = Some(now); - let signature = - signer.sign_account_announce(signer.validator_id(), &self.node_id, &next_epoch_id); + let announce_account = + AnnounceAccount::new(signer.as_ref(), self.node_id.clone(), next_epoch_id); self.network_adapter.send(PeerManagerMessageRequest::NetworkRequests( - NetworkRequests::AnnounceAccount(AnnounceAccount { - account_id: signer.validator_id().clone(), - peer_id: self.node_id.clone(), - epoch_id: next_epoch_id, - signature, - }), + NetworkRequests::AnnounceAccount(announce_account), )); } } diff --git a/chain/client/src/info.rs b/chain/client/src/info.rs index 6037b3fc490..5817374c5bd 100644 --- a/chain/client/src/info.rs +++ b/chain/client/src/info.rs @@ -615,12 +615,14 @@ impl InfoHelper { }, extra_info: serde_json::to_string(&extra_telemetry_info(client_config)).unwrap(), }; + + let mut json = serde_json::to_value(info).expect("Telemetry must serialize to JSON"); // Sign telemetry if there is a signer present. if let Some(signer) = signer { - signer.sign_telemetry(&info) - } else { - serde_json::to_value(&info).expect("Telemetry must serialize to json") + let content = serde_json::to_string(&json).expect("Telemetry must serialize to JSON"); + json["signature"] = signer.sign_bytes(content.as_bytes()).to_string().into(); } + json } fn log_chain_processing_info(&mut self, client: &crate::Client, epoch_id: &EpochId) { diff --git a/chain/network/src/network_protocol/testonly.rs b/chain/network/src/network_protocol/testonly.rs index d623e82b6b0..9147cb2b43f 100644 --- a/chain/network/src/network_protocol/testonly.rs +++ b/chain/network/src/network_protocol/testonly.rs @@ -105,18 +105,8 @@ pub fn make_peer_info(rng: &mut R) -> PeerInfo { pub fn make_announce_account(rng: &mut R) -> AnnounceAccount { let peer_id = make_peer_id(rng); - let validator_signer = make_validator_signer(rng); - let signature = validator_signer.sign_account_announce( - validator_signer.validator_id(), - &peer_id, - &EpochId::default(), - ); - AnnounceAccount { - account_id: validator_signer.validator_id().clone(), - peer_id: peer_id, - epoch_id: EpochId::default(), - signature, - } + let validator_signer = ValidatorSigner::InMemory(make_validator_signer(rng)); + AnnounceAccount::new(&validator_signer, peer_id, EpochId::default()) } pub fn make_partial_edge(rng: &mut R) -> PartialEdgeInfo { diff --git a/chain/network/src/peer_manager/tests/tier1.rs b/chain/network/src/peer_manager/tests/tier1.rs index 2a7945ddb59..94408997af8 100644 --- a/chain/network/src/peer_manager/tests/tier1.rs +++ b/chain/network/src/peer_manager/tests/tier1.rs @@ -22,7 +22,7 @@ fn make_block_approval(rng: &mut Rng, signer: &ValidatorSigner) -> Approval { let inner = ApprovalInner::Endorsement(data::make_hash(rng)); let target_height = rng.gen_range(0..100000); Approval { - signature: signer.sign_approval(&inner, target_height), + signature: signer.sign_bytes(&Approval::get_data_for_sig(&inner, target_height)), account_id: signer.validator_id().clone(), target_height, inner, diff --git a/core/primitives/src/block_header.rs b/core/primitives/src/block_header.rs index 786296fc782..5f47ea3425f 100644 --- a/core/primitives/src/block_header.rs +++ b/core/primitives/src/block_header.rs @@ -347,7 +347,8 @@ impl Approval { signer: &ValidatorSigner, ) -> Self { let inner = ApprovalInner::new(&parent_hash, parent_height, target_height); - let signature = signer.sign_approval(&inner, target_height); + + let signature = signer.sign_bytes(&Approval::get_data_for_sig(&inner, target_height)); Approval { inner, target_height, signature, account_id: signer.validator_id().clone() } } @@ -991,20 +992,14 @@ impl BlockHeader { where T: BorshSerialize + ?Sized, { + let hash = BlockHeader::compute_hash( + prev_hash, + &borsh::to_vec(&inner_lite).expect("Failed to serialize"), + &borsh::to_vec(&inner_rest).expect("Failed to serialize"), + ); match signature_source { - SignatureSource::Signer(signer) => signer.sign_block_header_parts( - prev_hash, - &borsh::to_vec(&inner_lite).expect("Failed to serialize"), - &borsh::to_vec(&inner_rest).expect("Failed to serialize"), - ), - SignatureSource::Signature(signature) => { - let hash = BlockHeader::compute_hash( - prev_hash, - &borsh::to_vec(&inner_lite).expect("Failed to serialize"), - &borsh::to_vec(&inner_rest).expect("Failed to serialize"), - ); - (hash, signature) - } + SignatureSource::Signer(signer) => (hash, signer.sign_bytes(hash.as_ref())), + SignatureSource::Signature(signature) => (hash, signature), } } diff --git a/core/primitives/src/challenge.rs b/core/primitives/src/challenge.rs index 5f9a3dbeb8c..7f3a1ed15f4 100644 --- a/core/primitives/src/challenge.rs +++ b/core/primitives/src/challenge.rs @@ -124,7 +124,8 @@ impl Challenge { } pub fn produce(body: ChallengeBody, signer: &ValidatorSigner) -> Self { - let (hash, signature) = signer.sign_challenge(&body); + let hash = CryptoHash::hash_borsh(&body); + let signature = signer.sign_bytes(hash.as_ref()); Self { body, account_id: signer.validator_id().clone(), signature, hash } } } diff --git a/core/primitives/src/network.rs b/core/primitives/src/network.rs index c3fb1d70214..2d2d781c830 100644 --- a/core/primitives/src/network.rs +++ b/core/primitives/src/network.rs @@ -1,5 +1,6 @@ use crate::hash::CryptoHash; use crate::types::{AccountId, EpochId}; +use crate::validator_signer::ValidatorSigner; use borsh::{BorshDeserialize, BorshSerialize}; use near_crypto::{PublicKey, Signature}; use near_schema_checker_lib::ProtocolSchema; @@ -67,17 +68,27 @@ pub struct AnnounceAccount { } impl AnnounceAccount { + pub fn new(signer: &ValidatorSigner, peer_id: PeerId, epoch_id: EpochId) -> Self { + let signature = Self::sign(signer, &peer_id, &epoch_id); + Self { account_id: signer.validator_id().clone(), peer_id: peer_id, epoch_id, signature } + } + + pub fn hash(&self) -> CryptoHash { + Self::build_header_hash(&self.account_id, &self.peer_id, &self.epoch_id) + } + + fn sign(signer: &ValidatorSigner, peer_id: &PeerId, epoch_id: &EpochId) -> Signature { + let hash = Self::build_header_hash(signer.validator_id(), peer_id, epoch_id); + signer.sign_bytes(hash.as_ref()) + } + /// We hash only (account_id, peer_id, epoch_id). There is no need hash the signature /// as it's uniquely determined the triple. - pub fn build_header_hash( + fn build_header_hash( account_id: &AccountId, peer_id: &PeerId, epoch_id: &EpochId, ) -> CryptoHash { CryptoHash::hash_borsh((account_id, peer_id, epoch_id)) } - - pub fn hash(&self) -> CryptoHash { - AnnounceAccount::build_header_hash(&self.account_id, &self.peer_id, &self.epoch_id) - } } diff --git a/core/primitives/src/sharding.rs b/core/primitives/src/sharding.rs index 2fce0513f22..e6628385821 100644 --- a/core/primitives/src/sharding.rs +++ b/core/primitives/src/sharding.rs @@ -215,7 +215,7 @@ impl ShardChunkHeaderV2 { prev_validator_proposals, }; let hash = Self::compute_hash(&inner); - let signature = signer.sign_chunk_hash(&hash); + let signature = signer.sign_bytes(hash.as_ref()); Self { inner, height_included: 0, signature, hash } } } @@ -331,7 +331,7 @@ impl ShardChunkHeaderV3 { pub fn from_inner(inner: ShardChunkHeaderInner, signer: &ValidatorSigner) -> Self { let hash = Self::compute_hash(&inner); - let signature = signer.sign_chunk_hash(&hash); + let signature = signer.sign_bytes(hash.as_ref()); Self { inner, height_included: 0, signature, hash } } } @@ -690,7 +690,7 @@ impl ShardChunkHeaderV1 { prev_validator_proposals, }; let hash = Self::compute_hash(&inner); - let signature = signer.sign_chunk_hash(&hash); + let signature = signer.sign_bytes(hash.as_ref()); Self { inner, height_included: 0, signature, hash } } } diff --git a/core/primitives/src/stateless_validation/chunk_endorsement.rs b/core/primitives/src/stateless_validation/chunk_endorsement.rs index 6f1c38260b7..d04e17b01a6 100644 --- a/core/primitives/src/stateless_validation/chunk_endorsement.rs +++ b/core/primitives/src/stateless_validation/chunk_endorsement.rs @@ -32,8 +32,8 @@ impl ChunkEndorsement { epoch_id, height_created: chunk_header.height_created(), }; - let signature = signer.sign_chunk_endorsement(&inner); - let metadata_signature = signer.sign_chunk_endorsement_metadata(&metadata); + let signature = signer.sign_bytes(&borsh::to_vec(&inner).unwrap()); + let metadata_signature = signer.sign_bytes(&borsh::to_vec(&metadata).unwrap()); let endorsement = ChunkEndorsementV2 { inner, signature, metadata, metadata_signature }; ChunkEndorsement::V2(endorsement) } diff --git a/core/primitives/src/stateless_validation/partial_witness.rs b/core/primitives/src/stateless_validation/partial_witness.rs index 95bb68c14b7..44d235b1657 100644 --- a/core/primitives/src/stateless_validation/partial_witness.rs +++ b/core/primitives/src/stateless_validation/partial_witness.rs @@ -55,7 +55,7 @@ impl PartialEncodedStateWitness { part, encoded_length, ); - let signature = signer.sign_partial_encoded_state_witness(&inner); + let signature = signer.sign_bytes(&borsh::to_vec(&inner).unwrap()); Self { inner, signature } } diff --git a/core/primitives/src/test_utils.rs b/core/primitives/src/test_utils.rs index 39053f260c4..625d63468d6 100644 --- a/core/primitives/src/test_utils.rs +++ b/core/primitives/src/test_utils.rs @@ -381,11 +381,12 @@ impl BlockHeader { } pub fn resign(&mut self, signer: &ValidatorSigner) { - let (hash, signature) = signer.sign_block_header_parts( + let hash = BlockHeader::compute_hash( *self.prev_hash(), &self.inner_lite_bytes(), &self.inner_rest_bytes(), ); + let signature = signer.sign_bytes(hash.as_ref()); match self { BlockHeader::BlockHeaderV1(header) => { let header = Arc::make_mut(header); diff --git a/core/primitives/src/validator_signer.rs b/core/primitives/src/validator_signer.rs index cf9b86026e0..a5b27ff068d 100644 --- a/core/primitives/src/validator_signer.rs +++ b/core/primitives/src/validator_signer.rs @@ -4,19 +4,7 @@ use std::sync::Arc; use near_crypto::{InMemorySigner, KeyType, PublicKey, Signature, Signer}; -use crate::block::{Approval, ApprovalInner, BlockHeader}; -use crate::challenge::ChallengeBody; -use crate::hash::CryptoHash; -use crate::network::{AnnounceAccount, PeerId}; -use crate::sharding::ChunkHash; -use crate::stateless_validation::chunk_endorsement::{ - ChunkEndorsementInner, ChunkEndorsementMetadata, -}; -use crate::stateless_validation::partial_witness::PartialEncodedStateWitnessInner; -use crate::stateless_validation::state_witness::EncodedChunkStateWitness; -use crate::telemetry::TelemetryInfo; -use crate::types::{AccountId, BlockHeight, EpochId}; -use crate::utils::compression::CompressedData; +use crate::types::AccountId; /// Enum for validator signer, that holds validator id and key used for signing data. #[derive(Clone, Debug, PartialEq)] @@ -45,107 +33,6 @@ impl ValidatorSigner { } } - /// Serializes telemetry info to JSON and signs it, returning JSON with "signature" field. - pub fn sign_telemetry(&self, info: &TelemetryInfo) -> serde_json::Value { - match self { - ValidatorSigner::Empty(signer) => signer.sign_telemetry(info), - ValidatorSigner::InMemory(signer) => signer.sign_telemetry(info), - } - } - - /// Signs given parts of the header. - pub fn sign_block_header_parts( - &self, - prev_hash: CryptoHash, - inner_lite: &[u8], - inner_rest: &[u8], - ) -> (CryptoHash, Signature) { - match self { - ValidatorSigner::Empty(signer) => { - signer.sign_block_header_parts(prev_hash, inner_lite, inner_rest) - } - ValidatorSigner::InMemory(signer) => { - signer.sign_block_header_parts(prev_hash, inner_lite, inner_rest) - } - } - } - - /// Signs given inner of the chunk header. - pub fn sign_chunk_hash(&self, chunk_hash: &ChunkHash) -> Signature { - match self { - ValidatorSigner::Empty(signer) => signer.sign_chunk_hash(chunk_hash), - ValidatorSigner::InMemory(signer) => signer.sign_chunk_hash(chunk_hash), - } - } - - /// Signs approval of given parent hash and reference hash. - pub fn sign_approval(&self, inner: &ApprovalInner, target_height: BlockHeight) -> Signature { - match self { - ValidatorSigner::Empty(signer) => signer.sign_approval(inner, target_height), - ValidatorSigner::InMemory(signer) => signer.sign_approval(inner, target_height), - } - } - - /// Signs chunk endorsement to be sent to block producer. - pub fn sign_chunk_endorsement(&self, inner: &ChunkEndorsementInner) -> Signature { - match self { - ValidatorSigner::Empty(signer) => signer.sign_chunk_endorsement(inner), - ValidatorSigner::InMemory(signer) => signer.sign_chunk_endorsement(inner), - } - } - - /// Signs chunk endorsement metadata. - pub fn sign_chunk_endorsement_metadata(&self, inner: &ChunkEndorsementMetadata) -> Signature { - match self { - ValidatorSigner::Empty(signer) => signer.sign_chunk_endorsement_metadata(inner), - ValidatorSigner::InMemory(signer) => signer.sign_chunk_endorsement_metadata(inner), - } - } - - /// Signs chunk state witness to be sent to all validators. - pub fn sign_chunk_state_witness(&self, witness_bytes: &EncodedChunkStateWitness) -> Signature { - match self { - ValidatorSigner::Empty(signer) => signer.sign_chunk_state_witness(witness_bytes), - ValidatorSigner::InMemory(signer) => signer.sign_chunk_state_witness(witness_bytes), - } - } - - /// Signs partial encoded state witness to be sent and forwarded to all validators. - pub fn sign_partial_encoded_state_witness( - &self, - part: &PartialEncodedStateWitnessInner, - ) -> Signature { - match self { - ValidatorSigner::Empty(signer) => signer.sign_partial_encoded_state_witness(part), - ValidatorSigner::InMemory(signer) => signer.sign_partial_encoded_state_witness(part), - } - } - - /// Signs challenge body. - pub fn sign_challenge(&self, challenge_body: &ChallengeBody) -> (CryptoHash, Signature) { - match self { - ValidatorSigner::Empty(signer) => signer.sign_challenge(challenge_body), - ValidatorSigner::InMemory(signer) => signer.sign_challenge(challenge_body), - } - } - - /// Signs account announce. - pub fn sign_account_announce( - &self, - account_id: &AccountId, - peer_id: &PeerId, - epoch_id: &EpochId, - ) -> Signature { - match self { - ValidatorSigner::Empty(signer) => { - signer.sign_account_announce(account_id, peer_id, epoch_id) - } - ValidatorSigner::InMemory(signer) => { - signer.sign_account_announce(account_id, peer_id, epoch_id) - } - } - } - pub fn sign_bytes(&self, data: &[u8]) -> Signature { match self { ValidatorSigner::Empty(signer) => signer.noop_signature(), @@ -208,60 +95,6 @@ impl EmptyValidatorSigner { fn noop_signature(&self) -> Signature { Signature::default() } - - fn sign_telemetry(&self, _info: &TelemetryInfo) -> serde_json::Value { - serde_json::Value::default() - } - - fn sign_block_header_parts( - &self, - prev_hash: CryptoHash, - inner_lite: &[u8], - inner_rest: &[u8], - ) -> (CryptoHash, Signature) { - let hash = BlockHeader::compute_hash(prev_hash, inner_lite, inner_rest); - (hash, Signature::default()) - } - - fn sign_chunk_hash(&self, _chunk_hash: &ChunkHash) -> Signature { - Signature::default() - } - - fn sign_approval(&self, _inner: &ApprovalInner, _target_height: BlockHeight) -> Signature { - Signature::default() - } - - fn sign_chunk_endorsement(&self, _inner: &ChunkEndorsementInner) -> Signature { - Signature::default() - } - - fn sign_chunk_endorsement_metadata(&self, _inner: &ChunkEndorsementMetadata) -> Signature { - Signature::default() - } - - fn sign_chunk_state_witness(&self, _witness_bytes: &EncodedChunkStateWitness) -> Signature { - Signature::default() - } - - fn sign_partial_encoded_state_witness( - &self, - _part: &PartialEncodedStateWitnessInner, - ) -> Signature { - Signature::default() - } - - fn sign_challenge(&self, challenge_body: &ChallengeBody) -> (CryptoHash, Signature) { - (CryptoHash::hash_borsh(challenge_body), Signature::default()) - } - - fn sign_account_announce( - &self, - _account_id: &AccountId, - _peer_id: &PeerId, - _epoch_id: &EpochId, - ) -> Signature { - Signature::default() - } } /// Signer that keeps secret key in memory and signs locally. @@ -303,66 +136,6 @@ impl InMemoryValidatorSigner { &self.account_id } - fn sign_telemetry(&self, info: &TelemetryInfo) -> serde_json::Value { - let mut value = serde_json::to_value(info).expect("Telemetry must serialize to JSON"); - let content = serde_json::to_string(&value).expect("Telemetry must serialize to JSON"); - value["signature"] = self.signer.sign(content.as_bytes()).to_string().into(); - value - } - - fn sign_block_header_parts( - &self, - prev_hash: CryptoHash, - inner_lite: &[u8], - inner_rest: &[u8], - ) -> (CryptoHash, Signature) { - let hash = BlockHeader::compute_hash(prev_hash, inner_lite, inner_rest); - (hash, self.signer.sign(hash.as_ref())) - } - - fn sign_chunk_hash(&self, chunk_hash: &ChunkHash) -> Signature { - self.signer.sign(chunk_hash.as_ref()) - } - - fn sign_approval(&self, inner: &ApprovalInner, target_height: BlockHeight) -> Signature { - self.signer.sign(&Approval::get_data_for_sig(inner, target_height)) - } - - fn sign_chunk_endorsement(&self, inner: &ChunkEndorsementInner) -> Signature { - self.signer.sign(&borsh::to_vec(inner).unwrap()) - } - - fn sign_chunk_endorsement_metadata(&self, inner: &ChunkEndorsementMetadata) -> Signature { - self.signer.sign(&borsh::to_vec(inner).unwrap()) - } - - fn sign_chunk_state_witness(&self, witness_bytes: &EncodedChunkStateWitness) -> Signature { - self.signer.sign(witness_bytes.as_slice()) - } - - fn sign_partial_encoded_state_witness( - &self, - part: &PartialEncodedStateWitnessInner, - ) -> Signature { - self.signer.sign(&borsh::to_vec(part).unwrap()) - } - - fn sign_challenge(&self, challenge_body: &ChallengeBody) -> (CryptoHash, Signature) { - let hash = CryptoHash::hash_borsh(challenge_body); - let signature = self.signer.sign(hash.as_ref()); - (hash, signature) - } - - pub fn sign_account_announce( - &self, - account_id: &AccountId, - peer_id: &PeerId, - epoch_id: &EpochId, - ) -> Signature { - let hash = AnnounceAccount::build_header_hash(account_id, peer_id, epoch_id); - self.signer.sign(hash.as_ref()) - } - fn sign_bytes(&self, bytes: &[u8]) -> Signature { self.signer.sign(bytes) } diff --git a/integration-tests/src/tests/client/process_blocks.rs b/integration-tests/src/tests/client/process_blocks.rs index c13d65b1b41..5ae98f4094e 100644 --- a/integration-tests/src/tests/client/process_blocks.rs +++ b/integration-tests/src/tests/client/process_blocks.rs @@ -3434,13 +3434,13 @@ fn test_header_version_downgrade() { BlockHeader::BlockHeaderV1(header) => { let header = Arc::make_mut(header); header.inner_rest.latest_protocol_version = PROTOCOL_VERSION; - let (hash, signature) = validator_signer.sign_block_header_parts( + let hash = BlockHeader::compute_hash( header.prev_hash, &borsh::to_vec(&header.inner_lite).expect("Failed to serialize"), &borsh::to_vec(&header.inner_rest).expect("Failed to serialize"), ); header.hash = hash; - header.signature = signature; + header.signature = validator_signer.sign_bytes(hash.as_ref()); } _ => { unreachable!();