sp_consensus_beefy/
witness.rs1use crate::commitment::{Commitment, SignedCommitment};
27use alloc::vec::Vec;
28
29#[derive(Debug, PartialEq, Eq, codec::Encode, codec::Decode)]
39pub struct SignedCommitmentWitness<TBlockNumber, TSignatureAccumulator> {
40 pub commitment: Commitment<TBlockNumber>,
42
43 pub signed_by: Vec<bool>, pub signature_accumulator: TSignatureAccumulator,
49}
50
51impl<TBlockNumber, TSignatureAccumulator>
52 SignedCommitmentWitness<TBlockNumber, TSignatureAccumulator>
53{
54 pub fn from_signed<TSignatureAggregator, TSignature>(
63 signed: SignedCommitment<TBlockNumber, TSignature>,
64 aggregator: TSignatureAggregator,
65 ) -> (Self, Vec<Option<TSignature>>)
66 where
67 TSignatureAggregator: FnOnce(&[Option<TSignature>]) -> TSignatureAccumulator,
68 {
69 let SignedCommitment { commitment, signatures } = signed;
70 let signed_by = signatures.iter().map(|s| s.is_some()).collect();
71 let signature_accumulator = aggregator(&signatures);
72
73 (Self { commitment, signed_by, signature_accumulator }, signatures)
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use sp_core::Pair;
80 use sp_crypto_hashing::keccak_256;
81
82 use super::*;
83 use codec::Decode;
84
85 use crate::{ecdsa_crypto::Signature as EcdsaSignature, known_payloads, Payload};
86
87 #[cfg(feature = "bls-experimental")]
88 use crate::bls_crypto::Signature as BlsSignature;
89
90 #[cfg(feature = "bls-experimental")]
91 use w3f_bls::{
92 single_pop_aggregator::SignatureAggregatorAssumingPoP, Message, SerializableToBytes,
93 Signed, TinyBLS381,
94 };
95
96 type TestCommitment = Commitment<u128>;
97
98 type TestEcdsaSignedCommitment = SignedCommitment<u128, EcdsaSignature>;
100 type TestEcdsaSignedCommitmentWitness =
101 SignedCommitmentWitness<u128, Vec<Option<EcdsaSignature>>>;
102
103 #[cfg(feature = "bls-experimental")]
104 #[derive(Clone, Debug, PartialEq, codec::Encode, codec::Decode)]
105 struct EcdsaBlsSignaturePair(EcdsaSignature, BlsSignature);
106
107 #[cfg(feature = "bls-experimental")]
109 type TestBlsSignedCommitment = SignedCommitment<u128, EcdsaBlsSignaturePair>;
110 #[cfg(feature = "bls-experimental")]
111 type TestBlsSignedCommitmentWitness = SignedCommitmentWitness<u128, Vec<u8>>;
112
113 fn mock_ecdsa_signatures() -> (EcdsaSignature, EcdsaSignature) {
115 let alice = sp_core::ecdsa::Pair::from_string("//Alice", None).unwrap();
116
117 let msg = keccak_256(b"This is the first message");
118 let sig1 = alice.sign_prehashed(&msg);
119
120 let msg = keccak_256(b"This is the second message");
121 let sig2 = alice.sign_prehashed(&msg);
122
123 (sig1.into(), sig2.into())
124 }
125
126 #[cfg(feature = "bls-experimental")]
129 fn mock_bls_signatures() -> (BlsSignature, BlsSignature) {
130 let alice = sp_core::bls::Pair::from_string("//Alice", None).unwrap();
131
132 let msg = b"This is the first message";
133 let sig1 = alice.sign(msg);
134
135 let msg = b"This is the second message";
136 let sig2 = alice.sign(msg);
137
138 (sig1.into(), sig2.into())
139 }
140
141 fn ecdsa_signed_commitment() -> TestEcdsaSignedCommitment {
142 let payload = Payload::from_single_entry(
143 known_payloads::MMR_ROOT_ID,
144 "Hello World!".as_bytes().to_vec(),
145 );
146 let commitment: TestCommitment =
147 Commitment { payload, block_number: 5, validator_set_id: 0 };
148
149 let sigs = mock_ecdsa_signatures();
150
151 SignedCommitment { commitment, signatures: vec![None, None, Some(sigs.0), Some(sigs.1)] }
152 }
153
154 #[cfg(feature = "bls-experimental")]
155 fn ecdsa_and_bls_signed_commitment() -> TestBlsSignedCommitment {
156 let payload = Payload::from_single_entry(
157 known_payloads::MMR_ROOT_ID,
158 "Hello World!".as_bytes().to_vec(),
159 );
160 let commitment: TestCommitment =
161 Commitment { payload, block_number: 5, validator_set_id: 0 };
162
163 let ecdsa_sigs = mock_ecdsa_signatures();
164 let bls_sigs = mock_bls_signatures();
165
166 SignedCommitment {
167 commitment,
168 signatures: vec![
169 None,
170 None,
171 Some(EcdsaBlsSignaturePair(ecdsa_sigs.0, bls_sigs.0)),
172 Some(EcdsaBlsSignaturePair(ecdsa_sigs.1, bls_sigs.1)),
173 ],
174 }
175 }
176
177 #[test]
178 fn should_convert_signed_commitment_to_witness() {
179 let signed = ecdsa_signed_commitment();
181
182 let (witness, signatures) =
184 TestEcdsaSignedCommitmentWitness::from_signed(signed, |sigs| sigs.to_vec());
185
186 assert_eq!(witness.signature_accumulator, signatures);
188 }
189
190 #[test]
191 #[cfg(feature = "bls-experimental")]
192 fn should_convert_dually_signed_commitment_to_witness() {
193 let signed = ecdsa_and_bls_signed_commitment();
195
196 let (witness, _signatures) =
198 TestBlsSignedCommitmentWitness::from_signed::<_, _>(signed, |sigs| {
200 let mut aggregatedsigs: SignatureAggregatorAssumingPoP<TinyBLS381> =
202 SignatureAggregatorAssumingPoP::new(Message::new(b"", b"mock payload"));
203
204 for sig in sigs {
205 match sig {
206 Some(sig) => {
207 let serialized_sig : Vec<u8> = (*sig.1).to_vec();
208 aggregatedsigs.add_signature(
209 &w3f_bls::Signature::<TinyBLS381>::from_bytes(
210 serialized_sig.as_slice()
211 ).unwrap()
212 );
213 },
214 None => (),
215 }
216 }
217 (&aggregatedsigs).signature().to_bytes()
218 });
219
220 w3f_bls::Signature::<TinyBLS381>::from_bytes(witness.signature_accumulator.as_slice())
223 .unwrap();
224 }
225
226 #[test]
227 fn should_encode_and_decode_witness() {
228 let signed = ecdsa_signed_commitment();
230 let (witness, _) = TestEcdsaSignedCommitmentWitness::from_signed::<_, _>(
231 signed,
232 |sigs: &[std::option::Option<EcdsaSignature>]| sigs.to_vec(),
233 );
234
235 let encoded = codec::Encode::encode(&witness);
237 let decoded = TestEcdsaSignedCommitmentWitness::decode(&mut &*encoded);
238
239 assert_eq!(decoded, Ok(witness));
241 assert_eq!(
242 encoded,
243 array_bytes::hex2bytes_unchecked(
244 "\
245 046d683048656c6c6f20576f726c642105000000000000000000000000000000000000000000000010\
246 0000010110000001558455ad81279df0795cc985580e4fb75d72d948d1107b2ac80a09abed4da8480c\
247 746cc321f2319a5e99a830e314d10dd3cd68ce3dc0c33c86e99bcb7816f9ba01012d6e1f8105c337a8\
248 6cdd9aaacdc496577f3db8c55ef9e6fd48f2c5c05a2274707491635d8ba3df64f324575b7b2a34487b\
249 ca2324b6a0046395a71681be3d0c2a00\
250 "
251 )
252 );
253 }
254}