sp_block_producer_metadata/
lib.rs1#![cfg_attr(not(feature = "std"), no_std)]
14#![deny(missing_docs)]
15
16use parity_scale_codec::{Decode, Encode};
17use sidechain_domain::*;
18use sp_api;
19extern crate alloc;
20
21#[derive(Debug, Clone, Encode)]
23pub struct MetadataSignedMessage<Metadata, AccountId> {
24 pub cross_chain_pub_key: CrossChainPublicKey,
26 pub metadata: Option<Metadata>,
28 pub genesis_utxo: UtxoId,
30 pub valid_before: u64,
34 pub owner: AccountId,
36}
37
38impl<M: Encode, AccountId: Encode> MetadataSignedMessage<M, AccountId> {
39 pub fn sign_with_key(&self, skey: &k256::SecretKey) -> CrossChainSignature {
41 use k256::Secp256k1;
42 use k256::ecdsa::hazmat::DigestPrimitive;
43 use k256::ecdsa::*;
44 use k256::sha2::Digest;
45 let data = self.encode();
46 let digest = <Secp256k1 as DigestPrimitive>::Digest::new_with_prefix(data);
47
48 let (sig, _recid) = SigningKey::from(skey).sign_digest_recoverable(digest.clone()).unwrap();
49 CrossChainSignature(sig.to_vec())
50 }
51
52 pub fn verify_signature(
54 &self,
55 vkey: &CrossChainPublicKey,
56 signature: CrossChainSignature,
57 ) -> Result<(), k256::ecdsa::signature::Error> {
58 signature.verify(vkey, &self.encode())
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65 use hex_literal::hex;
66
67 #[test]
68 fn round_trip() {
69 let message = MetadataSignedMessage {
70 cross_chain_pub_key: CrossChainPublicKey(vec![1; 32]),
71 metadata: Some("metadata".to_string()),
72 genesis_utxo: UtxoId::new([2; 32], 0),
73 valid_before: 100_000_000_000,
74 owner: 1000,
75 };
76
77 let skey = k256::SecretKey::from_slice(&hex!(
79 "cb6df9de1efca7a3998a8ead4e02159d5fa99c3e0d4fd6432667390bb4726854"
80 ))
81 .unwrap();
82 let vkey = skey.public_key();
83
84 let signature = message.sign_with_key(&skey);
85
86 assert!(message.verify_signature(&vkey.into(), signature).is_ok());
87 }
88}
89
90sp_api::decl_runtime_apis! {
91 pub trait BlockProducerMetadataApi<Metadata>
93 where Metadata:Decode
94 {
95 fn get_metadata_for(
97 cross_chain_pub_key: &CrossChainPublicKey,
98 ) -> Option<Metadata>;
99 }
100}