Repository: paritytech/substrate
File: client/statement-store/src/lib.rs (Rust)

Code before:
	/// will generally be the public key or a hash thereof for symmetric ciphers, or a hash of the
	/// private key for symmetric ciphers).
	fn posted(&self, match_all_topics: &[Topic], dest: [u8; 32]) -> Result<Vec<Vec<u8>>> {
		self.collect_statements(Some(dest), match_all_topics, |statement| statement.into_data())
	}

	/// Return the decrypted data of all known statements whose decryption key is identified as
	/// `dest`. The key must be available to the client.
	fn posted_clear(&self, match_all_topics: &[Topic], dest: [u8; 32]) -> Result<Vec<Vec<u8>>> {
		self.collect_statements(Some(dest), match_all_topics, |statement| {
			if let (Some(key), Some(_)) = (statement.decryption_key(), statement.data()) {
				let public = UncheckedFrom::unchecked_from(key);
				let mut out = None;
				if let Err(e) = self.keystore.with_ed25519_key(
					sp_core::crypto::key_types::STATEMENT,
					&public,
					&mut |pair| match statement.decrypt_private(pair) {
						Ok(r) => out = r,
						Err(e) => log::debug!(
							target: LOG_TARGET,
							"Decryption error: {:?}, for statement {:?}",
							e,
							HexDisplay::from(&statement.hash())
						),
					},
				) {
					log::debug!(
						target: LOG_TARGET,
						"Keystore error error: {:?}, for statement {:?}",
						e,
						HexDisplay::from(&statement.hash())
					)
				}
				out
			} else {
				None
			}
		})
	}

	/// Submit a statement to the store. Validates the statement and returns validation result.
	fn submit(&self, statement: Statement, source: StatementSource) -> SubmitResult {
		let hash = statement.hash();
		match self.index.read().query(&hash) {
			IndexQuery::Expired =>
				if !source.can_be_resubmitted() {
					return SubmitResult::KnownExpired
				},
			IndexQuery::Exists =>
				if !source.can_be_resubmitted() {
					return SubmitResult::Known

Review comment (suggestion):
We can have with_ed25519_key use a function that return an error as param, and potentially have posted clear report this in its list for results.

Code after:
	/// field.
	fn broadcasts(&self, match_all_topics: &[Topic]) -> Result<Vec<Vec<u8>>> {
		self.collect_statements(None, match_all_topics, |statement| statement.into_data())
	}

	/// Return the data of all known statements whose decryption key is identified as `dest` (this
	/// will generally be the public key or a hash thereof for symmetric ciphers, or a hash of the
	/// private key for symmetric ciphers).
	fn posted(&self, match_all_topics: &[Topic], dest: [u8; 32]) -> Result<Vec<Vec<u8>>> {
		self.collect_statements(Some(dest), match_all_topics, |statement| statement.into_data())
	}

	/// Return the decrypted data of all known statements whose decryption key is identified as
	/// `dest`. The key must be available to the client.
	fn posted_clear(&self, match_all_topics: &[Topic], dest: [u8; 32]) -> Result<Vec<Vec<u8>>> {
		self.collect_statements(Some(dest), match_all_topics, |statement| {
			if let (Some(key), Some(_)) = (statement.decryption_key(), statement.data()) {
				let public: sp_core::ed25519::Public = UncheckedFrom::unchecked_from(key);
				let public: sp_statement_store::ed25519::Public = public.into();
				match self.keystore.key_pair::<sp_statement_store::ed25519::Pair>(&public) {
					Err(e) => {
						log::debug!(
							target: LOG_TARGET,
							"Keystore error: {:?}, for statement {:?}",
							e,
							HexDisplay::from(&statement.hash())
						);
						None
					},
					Ok(None) => {
						log::debug!(
							target: LOG_TARGET,
							"Keystore is missing key for statement {:?}",
							HexDisplay::from(&statement.hash())
						);
						None
					},
					Ok(Some(pair)) => match statement.decrypt_private(&pair.into_inner()) {
						Ok(r) => r,
						Err(e) => {
							log::debug!(
								target: LOG_TARGET,
								"Decryption error: {:?}, for statement {:?}",
								e,
								HexDisplay::from(&statement.hash())
							);
							None
						},
					},
				}
			} else {