1use ciborium::{from_reader, into_writer, Value};
2use serde::{de, ser, Deserialize, Serialize};
3use sha3::{Digest, Sha3_256};
4use std::{borrow::BorrowMut, fmt::Debug};
5
6use crate::ns::{
7 kind_of_value, Bytes32, Error, IntValue, Name, PublicKeyParams, Service, ThresholdLevel,
8};
9
10pub const NAME_STALE_SECONDS: u64 = 60 * 60 * 24 * 365;
12pub const NAME_EXPIRE_SECONDS: u64 = NAME_STALE_SECONDS + 60 * 60 * 24 * 180;
14
15#[derive(Debug, Default, Clone, PartialEq)]
16pub struct NameState {
17 pub name: String,
18 pub sequence: u64,
19 pub block_height: u64,
20 pub block_time: u64,
21 pub stale_time: u64,
22 pub expire_time: u64,
23 pub threshold: u8,
24 pub key_kind: u8,
25 pub public_keys: Vec<Bytes32>,
26 pub next_public_keys: Option<Vec<Bytes32>>,
27}
28
29impl From<&NameState> for Value {
30 fn from(state: &NameState) -> Self {
31 let mut arr = vec![
32 Value::from(state.name.clone()),
33 Value::from(state.sequence),
34 Value::from(state.block_height),
35 Value::from(state.block_time),
36 Value::from(state.stale_time),
37 Value::from(state.expire_time),
38 Value::from(state.threshold),
39 Value::from(state.key_kind),
40 Value::Array(state.public_keys.iter().map(Value::from).collect()),
41 ];
42 if let Some(keys) = state.next_public_keys.as_ref() {
43 arr.push(Value::Array(keys.iter().map(Value::from).collect()));
44 }
45 Value::Array(arr)
46 }
47}
48
49impl TryFrom<&Value> for NameState {
50 type Error = Error;
51
52 fn try_from(value: &Value) -> Result<Self, Self::Error> {
53 let arr = value.as_array().ok_or_else(|| {
54 Error::Custom(format!(
55 "NameState: expected array, got {}",
56 kind_of_value(value)
57 ))
58 })?;
59 match arr.len() {
60 9 | 10 => {
61 let mut state = NameState {
62 name: arr[0]
63 .as_text()
64 .ok_or_else(|| {
65 Error::Custom(format!(
66 "NameState: expected string, got {}",
67 kind_of_value(&arr[0])
68 ))
69 })?
70 .to_string(),
71 sequence: u64::try_from(&IntValue(&arr[1]))?,
72 block_height: u64::try_from(&IntValue(&arr[2]))?,
73 block_time: u64::try_from(&IntValue(&arr[3]))?,
74 stale_time: u64::try_from(&IntValue(&arr[4]))?,
75 expire_time: u64::try_from(&IntValue(&arr[5]))?,
76 threshold: u8::try_from(&IntValue(&arr[6]))?,
77 key_kind: u8::try_from(&IntValue(&arr[7]))?,
78 public_keys: Bytes32::vec_try_from_value(&arr[8])?,
79 ..Default::default()
80 };
81 if arr.len() == 10 {
82 state.next_public_keys = Some(Bytes32::vec_try_from_value(&arr[9])?);
83 }
84 Ok(state)
85 }
86 _ => Err(Error::Custom(format!(
87 "NameState: expected array of length 9 or 10, got {}",
88 arr.len()
89 ))),
90 }
91 }
92}
93
94impl NameState {
95 pub fn public_key_params(&self) -> PublicKeyParams {
96 PublicKeyParams {
97 public_keys: self.public_keys.clone(),
98 threshold: Some(self.threshold),
99 kind: Some(self.key_kind),
100 }
101 }
102
103 pub fn hash(&self) -> Result<Bytes32, Error> {
104 hash_sha3(self)
105 }
106
107 pub fn verify_the_next(
108 &self,
109 block_height: u64,
110 block_time: u64,
111 next: &Name,
112 ) -> Result<NameState, Error> {
113 if self.name != next.name {
115 return Err(Error::Custom("name mismatch".to_string()));
116 }
117 if self.sequence + 1 != next.sequence {
118 return Err(Error::Custom(format!(
119 "invalid sequence, expected: {}, got: {}",
120 self.sequence + 1,
121 next.sequence
122 )));
123 }
124
125 if next.service.code != 0 {
126 next.verify(&self.public_key_params(), ThresholdLevel::Default)?;
127 return Ok(NameState {
128 name: next.name.clone(),
129 sequence: next.sequence,
130 block_height,
131 block_time,
132 stale_time: block_time + NAME_STALE_SECONDS,
133 expire_time: block_time + NAME_EXPIRE_SECONDS,
134 threshold: self.threshold,
135 key_kind: self.key_kind,
136 public_keys: self.public_keys.clone(),
137 next_public_keys: None,
138 });
139 }
140
141 let mut next_state = self.clone();
143 if next.service.operations.len() == 1 && next.service.operations[0].subcode == 0 {
144 next.verify(&next_state.public_key_params(), ThresholdLevel::Default)?;
146 next_state.sequence = next.sequence;
147 next_state.block_height = block_height;
148 next_state.block_time = block_time;
149 next_state.stale_time = block_time + NAME_STALE_SECONDS;
150 next_state.expire_time = block_time + NAME_EXPIRE_SECONDS;
151 next_state.next_public_keys = None;
152 return Ok(next_state);
153 }
154
155 for op in &next.service.operations {
156 let public_key_params = PublicKeyParams::try_from(&op.params)?;
157 public_key_params.validate()?;
158 match op.subcode {
159 2 => {
160 next.verify(&next_state.public_key_params(), ThresholdLevel::Strict)?;
162 next_state = NameState {
163 name: next.name.clone(),
164 sequence: next.sequence,
165 block_height,
166 block_time,
167 stale_time: block_time + NAME_STALE_SECONDS,
168 expire_time: block_time + NAME_EXPIRE_SECONDS,
169 threshold: next_state.threshold,
170 key_kind: next_state.key_kind,
171 public_keys: next_state.public_keys.clone(),
172 next_public_keys: Some(public_key_params.public_keys),
173 };
174 }
175 1 => {
176 let allow_update = (next_state.expire_time < block_time)
178 || (next_state.next_public_keys.is_some()
179 && next_state.next_public_keys.as_ref().unwrap()
180 == &public_key_params.public_keys);
181
182 if !allow_update {
183 return Err(Error::Custom(
184 "public_keys mismatch, or name is not expired".to_string(),
185 ));
186 }
187
188 next_state = NameState {
189 name: next.name.clone(),
190 sequence: next.sequence,
191 block_height,
192 block_time,
193 stale_time: block_time + NAME_STALE_SECONDS,
194 expire_time: block_time + NAME_EXPIRE_SECONDS,
195 threshold: public_key_params
196 .threshold
197 .unwrap_or(public_key_params.public_keys.len() as u8),
198 key_kind: public_key_params.kind.unwrap_or(0),
199 public_keys: public_key_params.public_keys,
200 next_public_keys: None,
201 };
202 next.verify(&next_state.public_key_params(), ThresholdLevel::All)?;
203 }
204 v => return Err(Error::Custom(format!("invalid operation subcode: {}", v))),
205 }
206 }
207
208 Ok(next_state)
209 }
210}
211
212#[derive(Debug, Default, Clone, PartialEq)]
213pub struct ServiceState {
214 pub name: String,
215 pub code: u64,
216 pub sequence: u64,
217 pub data: Vec<(u16, Value)>,
218}
219
220impl From<&ServiceState> for Value {
221 fn from(state: &ServiceState) -> Self {
222 Value::Array(vec![
223 Value::from(state.name.clone()),
224 Value::from(state.code),
225 Value::from(state.sequence),
226 Value::Map(
227 state
228 .data
229 .iter()
230 .map(|(subcode, params)| (Value::from(*subcode), params.clone()))
231 .collect(),
232 ),
233 ])
234 }
235}
236
237impl TryFrom<&Value> for ServiceState {
238 type Error = Error;
239
240 fn try_from(value: &Value) -> Result<Self, Self::Error> {
241 let arr = value.as_array().ok_or_else(|| {
242 Error::Custom(format!(
243 "ServiceState: expected array, got {}",
244 kind_of_value(value)
245 ))
246 })?;
247 match arr.len() {
248 4 => {
249 let state = ServiceState {
250 name: arr[0]
251 .as_text()
252 .ok_or_else(|| {
253 Error::Custom(format!(
254 "ServiceState: expected string, got {}",
255 kind_of_value(&arr[0])
256 ))
257 })?
258 .to_string(),
259 code: u64::try_from(&IntValue(&arr[1]))?,
260 sequence: u64::try_from(&IntValue(&arr[2]))?,
261 data: arr[3]
262 .as_map()
263 .ok_or_else(|| {
264 Error::Custom(format!(
265 "ServiceState: expected map, got {}",
266 kind_of_value(&arr[3])
267 ))
268 })?
269 .iter()
270 .map(|(k, v)| {
271 let subcode = u16::try_from(&IntValue(k))?;
272 Ok((subcode, v.clone()))
273 })
274 .collect::<Result<Vec<(u16, Value)>, Error>>()?,
275 };
276 Ok(state)
277 }
278 _ => Err(Error::Custom(format!(
279 "ServiceState: expected array of length 4, got {}",
280 arr.len()
281 ))),
282 }
283 }
284}
285
286impl ServiceState {
287 pub fn hash(&self) -> Result<Bytes32, Error> {
288 hash_sha3(self)
289 }
290
291 pub fn verify_the_next(&self, next: &Name) -> Result<ServiceState, Error> {
292 if self.name != next.name {
294 return Err(Error::Custom("name mismatch".to_string()));
295 }
296 if self.sequence + 1 != next.sequence {
297 return Err(Error::Custom(format!(
298 "invalid sequence, expected: {}, got: {}",
299 self.sequence + 1,
300 next.sequence
301 )));
302 }
303
304 if next.service.code != self.code {
305 return Err(Error::Custom(format!(
306 "invalid service code, expected: {}, got: {}",
307 self.code, next.service.code
308 )));
309 }
310
311 let mut next_state = ServiceState {
312 name: next.name.clone(),
313 code: next.service.code,
314 sequence: next.sequence,
315 data: self.data.clone(),
316 };
317 for op in &next.service.operations {
318 if let Some(i) = next_state.data.iter().position(|v| v.0 == op.subcode) {
319 next_state.data[i].1 = op.params.clone();
322 } else {
323 next_state.data.push((op.subcode, op.params.clone()));
324 }
325 }
326 next_state
327 .data
328 .sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap());
329
330 Ok(next_state)
331 }
332}
333
334#[derive(Debug, Clone, PartialEq)]
335pub struct ServiceProtocol {
336 pub code: u64,
337 pub version: u16,
338 pub protocol: Value,
339 pub submitter: String,
340 pub sequence: u64,
341}
342
343impl Default for ServiceProtocol {
344 fn default() -> Self {
345 Self {
346 code: 0,
347 version: 0,
348 protocol: Value::Null,
349 submitter: "".to_string(),
350 sequence: 0,
351 }
352 }
353}
354
355impl From<&ServiceProtocol> for Value {
356 fn from(state: &ServiceProtocol) -> Self {
357 Value::Array(vec![
358 Value::from(state.code),
359 Value::from(state.version),
360 state.protocol.clone(),
361 Value::from(state.submitter.clone()),
362 Value::from(state.sequence),
363 ])
364 }
365}
366
367impl TryFrom<&Value> for ServiceProtocol {
368 type Error = Error;
369
370 fn try_from(value: &Value) -> Result<Self, Self::Error> {
371 let arr = value.as_array().ok_or_else(|| {
372 Error::Custom(format!(
373 "ServiceProtocol: expected array, got {}",
374 kind_of_value(value)
375 ))
376 })?;
377 match arr.len() {
378 5 => {
379 let state = ServiceProtocol {
380 code: u64::try_from(&IntValue(&arr[0]))?,
381 version: u16::try_from(&IntValue(&arr[1]))?,
382 protocol: arr[2].clone(),
383 submitter: arr[3]
384 .as_text()
385 .ok_or_else(|| {
386 Error::Custom(format!(
387 "ServiceProtocol: expected string, got {}",
388 kind_of_value(&arr[0])
389 ))
390 })?
391 .to_string(),
392 sequence: u64::try_from(&IntValue(&arr[4]))?,
393 };
394 Ok(state)
395 }
396 _ => Err(Error::Custom(format!(
397 "ServiceProtocol: expected array of length 4, got {}",
398 arr.len()
399 ))),
400 }
401 }
402}
403
404impl ServiceProtocol {
405 pub fn hash(&self) -> Result<Bytes32, Error> {
406 hash_sha3(self)
407 }
408
409 pub fn validate(&self, service: &Service) -> Result<(), Error> {
410 if self.code != service.code {
411 return Err(Error::Custom(format!(
412 "invalid service code, expected: {}, got: {}",
413 self.code, service.code
414 )));
415 }
416
417 match self.code {
419 0 => {
420 Ok(())
422 }
423 v => Err(Error::Custom(format!("invalid service code: {}", v))),
424 }
425 }
426}
427
428#[derive(Debug, Default, Clone, PartialEq)]
429pub struct Inscription {
430 pub name: String,
431 pub sequence: u64,
432 pub height: u64,
433 pub name_height: u64,
434 pub previous_hash: Bytes32,
435 pub name_hash: Bytes32,
436 pub service_hash: Bytes32,
437 pub protocol_hash: Option<Bytes32>,
438 pub block_height: u64,
439 pub block_hash: Bytes32,
440 pub txid: Bytes32,
441 pub vin: u8,
442 pub data: Name,
443}
444
445impl From<&Inscription> for Value {
446 fn from(state: &Inscription) -> Self {
447 let mut arr = vec![
448 Value::from(state.name.clone()),
449 Value::from(state.sequence),
450 Value::from(state.height),
451 Value::Array(vec![
452 Value::from(state.name_height),
453 Value::from(&state.previous_hash),
454 Value::from(&state.name_hash),
455 Value::from(&state.service_hash),
456 ]),
457 Value::Array(vec![
458 Value::from(state.block_height),
459 Value::from(&state.block_hash),
460 Value::from(&state.txid),
461 Value::from(state.vin),
462 ]),
463 Value::from(&state.data),
464 ];
465 if let Some(ref hash) = state.protocol_hash {
466 arr[3].as_array_mut().unwrap().push(Value::from(hash));
467 }
468 Value::Array(arr)
469 }
470}
471
472impl TryFrom<&Value> for Inscription {
473 type Error = Error;
474
475 fn try_from(value: &Value) -> Result<Self, Self::Error> {
476 let arr = value.as_array().ok_or_else(|| {
477 Error::Custom(format!(
478 "Inscription: expected array, got {}",
479 kind_of_value(value)
480 ))
481 })?;
482 match arr.len() {
483 6 => {
484 let ins_state = arr[3].as_array().ok_or_else(|| {
485 Error::Custom(format!(
486 "Inscription: expected array at 3, got {}",
487 kind_of_value(&arr[3])
488 ))
489 })?;
490 if ins_state.len() != 4 && ins_state.len() != 5 {
491 return Err(Error::Custom(format!(
492 "Inscription: expected array of length 4 or 5 at 3, got {}",
493 ins_state.len()
494 )));
495 }
496 let tx_state = arr[4].as_array().ok_or_else(|| {
497 Error::Custom(format!(
498 "Inscription: expected array at 4, got {}",
499 kind_of_value(&arr[3])
500 ))
501 })?;
502 if tx_state.len() != 4 {
503 return Err(Error::Custom(format!(
504 "Inscription: expected array of length 4 at 4, got {}",
505 tx_state.len()
506 )));
507 }
508
509 let mut ins = Inscription {
510 name: arr[0]
511 .as_text()
512 .ok_or_else(|| {
513 Error::Custom(format!(
514 "Inscription: expected string, got {}",
515 kind_of_value(&arr[0])
516 ))
517 })?
518 .to_string(),
519 sequence: u64::try_from(&IntValue(&arr[1]))?,
520 height: u64::try_from(&IntValue(&arr[2]))?,
521 name_height: u64::try_from(&IntValue(&ins_state[0]))?,
522 previous_hash: Bytes32::try_from(&ins_state[1])?,
523 name_hash: Bytes32::try_from(&ins_state[2])?,
524 service_hash: Bytes32::try_from(&ins_state[3])?,
525 protocol_hash: None,
526 block_height: u64::try_from(&IntValue(&tx_state[0]))?,
527 block_hash: Bytes32::try_from(&tx_state[1])?,
528 txid: Bytes32::try_from(&tx_state[2])?,
529 vin: u8::try_from(&IntValue(&tx_state[3]))?,
530 data: Name::try_from(&arr[5])?,
531 };
532 if ins_state.len() == 5 {
533 ins.protocol_hash = Some(Bytes32::try_from(&ins_state[4])?);
534 }
535
536 Ok(ins)
537 }
538 _ => Err(Error::Custom(format!(
539 "Inscription: expected array of length 4, got {}",
540 arr.len()
541 ))),
542 }
543 }
544}
545
546impl Inscription {
547 pub fn hash(&self) -> Result<Bytes32, Error> {
548 hash_sha3(self)
549 }
550}
551
552#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq)]
553pub struct InvalidInscription {
554 pub name: String,
555 pub block_height: u64,
556 pub hash: Bytes32,
557 pub reason: String,
558 pub data: Name,
559}
560
561impl InvalidInscription {}
562
563impl Serialize for NameState {
564 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
565 where
566 S: ser::Serializer,
567 {
568 Value::from(self).serialize(serializer)
569 }
570}
571
572impl<'de> Deserialize<'de> for NameState {
573 fn deserialize<D>(deserializer: D) -> Result<NameState, D::Error>
574 where
575 D: de::Deserializer<'de>,
576 {
577 let val = Value::deserialize(deserializer)?;
578 NameState::try_from(&val).map_err(de::Error::custom)
579 }
580}
581
582impl Serialize for ServiceState {
583 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
584 where
585 S: ser::Serializer,
586 {
587 Value::from(self).serialize(serializer)
588 }
589}
590
591impl<'de> Deserialize<'de> for ServiceState {
592 fn deserialize<D>(deserializer: D) -> Result<ServiceState, D::Error>
593 where
594 D: de::Deserializer<'de>,
595 {
596 let val = Value::deserialize(deserializer)?;
597 ServiceState::try_from(&val).map_err(de::Error::custom)
598 }
599}
600
601impl Serialize for ServiceProtocol {
602 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
603 where
604 S: ser::Serializer,
605 {
606 Value::from(self).serialize(serializer)
607 }
608}
609
610impl<'de> Deserialize<'de> for ServiceProtocol {
611 fn deserialize<D>(deserializer: D) -> Result<ServiceProtocol, D::Error>
612 where
613 D: de::Deserializer<'de>,
614 {
615 let val = Value::deserialize(deserializer)?;
616 ServiceProtocol::try_from(&val).map_err(de::Error::custom)
617 }
618}
619
620impl Serialize for Inscription {
621 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
622 where
623 S: ser::Serializer,
624 {
625 Value::from(self).serialize(serializer)
626 }
627}
628
629impl<'de> Deserialize<'de> for Inscription {
630 fn deserialize<D>(deserializer: D) -> Result<Inscription, D::Error>
631 where
632 D: de::Deserializer<'de>,
633 {
634 let val = Value::deserialize(deserializer)?;
635 Inscription::try_from(&val).map_err(de::Error::custom)
636 }
637}
638
639pub fn from_bytes<T>(bytes: &[u8]) -> Result<T, Error>
640where
641 T: de::DeserializeOwned,
642{
643 let value = from_reader(bytes).map_err(|err| Error::Custom(err.to_string()))?;
644 Ok(value)
645}
646
647pub fn to_bytes<T: Serialize>(value: &T) -> Result<Vec<u8>, Error> {
648 let mut buf: Vec<u8> = Vec::new();
649 into_writer(value, &mut buf).map_err(|err| Error::Custom(err.to_string()))?;
650 Ok(buf)
651}
652
653pub fn hash_sha3<T: Serialize>(value: &T) -> Result<Bytes32, Error> {
654 let mut hasher = Sha3_256::new();
655 into_writer(value, hasher.borrow_mut())
656 .map_err(|err| Error::Custom(format!("hash_sha3: {:?}", err)))?;
657 Bytes32::try_from(hasher.finalize().as_slice())
658}
659
660#[cfg(test)]
661mod tests {
662 use super::*;
663 use rand_core::{OsRng, RngCore};
664
665 use crate::{ed25519, ns};
666
667 fn secret_key() -> [u8; 32] {
668 let mut data = [0u8; 32];
669 OsRng.fill_bytes(&mut data);
670 data
671 }
672
673 #[test]
674 fn name_state_works() {
675 let s1 = ed25519::SigningKey::from_bytes(&secret_key());
676 let s2 = ed25519::SigningKey::from_bytes(&secret_key());
677 let s3 = ed25519::SigningKey::from_bytes(&secret_key());
678
679 let name_state = NameState {
680 name: "test".to_string(),
681 sequence: 0,
682 block_height: 1,
683 block_time: 1,
684 threshold: 1,
685 public_keys: vec![s1.verifying_key().to_bytes().into()],
686 ..Default::default()
687 };
688
689 let mut next_name = ns::Name {
690 name: "test".to_string(),
691 sequence: 1,
692 service: ns::Service {
693 code: 0,
694 operations: vec![ns::Operation {
695 subcode: 1,
696 params: ns::Value::from(&ns::PublicKeyParams {
697 public_keys: vec![
698 s1.verifying_key().to_bytes().into(),
699 s2.verifying_key().to_bytes().into(),
700 ],
701 threshold: None,
702 kind: None,
703 }),
704 }],
705 attesters: None,
706 },
707 signatures: vec![],
708 };
709 next_name
710 .sign(
711 &name_state.public_key_params(),
712 ns::ThresholdLevel::Default,
713 &[s1.clone()],
714 )
715 .unwrap();
716 next_name.validate().unwrap();
717
718 assert!(
719 name_state.verify_the_next(3, 3, &next_name).is_err(),
720 "do not allow update"
721 );
722
723 let mut next_name = ns::Name {
724 name: "test".to_string(),
725 sequence: 1,
726 service: ns::Service {
727 code: 0,
728 operations: vec![ns::Operation {
729 subcode: 2,
730 params: ns::Value::from(&ns::PublicKeyParams {
731 public_keys: vec![
732 s1.verifying_key().to_bytes().into(),
733 s2.verifying_key().to_bytes().into(),
734 ],
735 threshold: None,
736 kind: None,
737 }),
738 }],
739 attesters: None,
740 },
741 signatures: vec![],
742 };
743 next_name
744 .sign(
745 &name_state.public_key_params(),
746 ns::ThresholdLevel::Default,
747 &[s1.clone()],
748 )
749 .unwrap();
750 next_name.validate().unwrap();
751
752 let name_state = name_state.verify_the_next(3, 3, &next_name).unwrap();
753 assert_eq!(1, name_state.sequence);
754 assert_eq!(3, name_state.block_height);
755 assert_eq!(3, name_state.block_time);
756 assert_eq!(3 + NAME_STALE_SECONDS, name_state.stale_time);
757 assert_eq!(3 + NAME_EXPIRE_SECONDS, name_state.expire_time);
758 assert_eq!(1, name_state.threshold);
759 assert_eq!(0, name_state.key_kind);
760 assert_eq!(
761 vec![Bytes32::from(s1.verifying_key().to_bytes())],
762 name_state.public_keys
763 );
764 assert_eq!(
765 Some(vec![
766 s1.verifying_key().to_bytes().into(),
767 s2.verifying_key().to_bytes().into()
768 ]),
769 name_state.next_public_keys
770 );
771
772 let mut next_name = ns::Name {
773 name: "test".to_string(),
774 sequence: 2,
775 service: ns::Service {
776 code: 0,
777 operations: vec![ns::Operation {
778 subcode: 1,
779 params: ns::Value::from(&ns::PublicKeyParams {
780 public_keys: vec![
781 s1.verifying_key().to_bytes().into(),
782 s2.verifying_key().to_bytes().into(),
783 ],
784 threshold: None,
785 kind: None,
786 }),
787 }],
788 attesters: None,
789 },
790 signatures: vec![],
791 };
792 next_name
793 .sign(
794 &name_state.public_key_params(),
795 ns::ThresholdLevel::Default,
796 &[s1.clone()],
797 )
798 .unwrap();
799 next_name.validate().unwrap();
800
801 assert!(
802 name_state.verify_the_next(5, 5, &next_name).is_err(),
803 "invalid signatures"
804 );
805
806 next_name
807 .sign(
808 &ns::PublicKeyParams {
809 public_keys: vec![
810 s1.verifying_key().to_bytes().into(),
811 s2.verifying_key().to_bytes().into(),
812 ],
813 threshold: None,
814 kind: None,
815 },
816 ns::ThresholdLevel::All,
817 &[s1.clone(), s2.clone()],
818 )
819 .unwrap();
820 next_name.validate().unwrap();
821
822 let name_state = name_state.verify_the_next(5, 5, &next_name).unwrap();
823 assert_eq!(2, name_state.sequence);
824 assert_eq!(5, name_state.block_height);
825 assert_eq!(5, name_state.block_time);
826 assert_eq!(5 + NAME_STALE_SECONDS, name_state.stale_time);
827 assert_eq!(5 + NAME_EXPIRE_SECONDS, name_state.expire_time);
828 assert_eq!(2, name_state.threshold);
829 assert_eq!(0, name_state.key_kind);
830 assert_eq!(
831 vec![
832 Bytes32::from(s1.verifying_key().to_bytes()),
833 Bytes32::from(s2.verifying_key().to_bytes()),
834 ],
835 name_state.public_keys
836 );
837 assert_eq!(None, name_state.next_public_keys);
838
839 let mut next_name = ns::Name {
841 name: "test".to_string(),
842 sequence: 3,
843 service: ns::Service {
844 code: 0,
845 operations: vec![
846 ns::Operation {
847 subcode: 2,
848 params: ns::Value::from(&ns::PublicKeyParams {
849 public_keys: vec![s3.verifying_key().to_bytes().into()],
850 threshold: None,
851 kind: None,
852 }),
853 },
854 ns::Operation {
855 subcode: 1,
856 params: ns::Value::from(&ns::PublicKeyParams {
857 public_keys: vec![s3.verifying_key().to_bytes().into()],
858 threshold: None,
859 kind: None,
860 }),
861 },
862 ],
863 attesters: None,
864 },
865 signatures: vec![],
866 };
867 next_name
868 .sign(
869 &name_state.public_key_params(),
870 ns::ThresholdLevel::Default,
871 &[s1.clone(), s2.clone()],
872 )
873 .unwrap();
874
875 next_name.validate().unwrap();
876 assert!(
877 name_state.verify_the_next(7, 7, &next_name).is_err(),
878 "invalid signatures"
879 );
880
881 next_name.sign_with(&s3).unwrap();
882 assert_eq!(3, next_name.signatures.len());
883 let name_state = name_state.verify_the_next(7, 7, &next_name).unwrap();
884 assert_eq!(3, name_state.sequence);
885 assert_eq!(7, name_state.block_height);
886 assert_eq!(7, name_state.block_time);
887 assert_eq!(7 + NAME_STALE_SECONDS, name_state.stale_time);
888 assert_eq!(7 + NAME_EXPIRE_SECONDS, name_state.expire_time);
889 assert_eq!(1, name_state.threshold);
890 assert_eq!(0, name_state.key_kind);
891 assert_eq!(
892 vec![Bytes32::from(s3.verifying_key().to_bytes())],
893 name_state.public_keys
894 );
895 assert_eq!(None, name_state.next_public_keys);
896
897 let mut next_name = ns::Name {
899 name: "test".to_string(),
900 sequence: 4,
901 service: ns::Service {
902 code: 0,
903 operations: vec![ns::Operation {
904 subcode: 1,
905 params: ns::Value::from(&ns::PublicKeyParams {
906 public_keys: vec![
907 s2.verifying_key().to_bytes().into(),
908 s1.verifying_key().to_bytes().into(),
909 ],
910 threshold: Some(1),
911 kind: None,
912 }),
913 }],
914 attesters: None,
915 },
916 signatures: vec![],
917 };
918
919 next_name.sign_with(&s1).unwrap();
920 next_name.sign_with(&s2).unwrap();
921 next_name.validate().unwrap();
922
923 let block_time = name_state.expire_time + 1;
924 let name_state = name_state
925 .verify_the_next(8, block_time, &next_name)
926 .unwrap();
927 assert_eq!(4, name_state.sequence);
928 assert_eq!(8, name_state.block_height);
929 assert_eq!(block_time, name_state.block_time);
930 assert_eq!(block_time + NAME_STALE_SECONDS, name_state.stale_time);
931 assert_eq!(block_time + NAME_EXPIRE_SECONDS, name_state.expire_time);
932 assert_eq!(1, name_state.threshold);
933 assert_eq!(0, name_state.key_kind);
934 assert_eq!(
935 vec![
936 Bytes32::from(s2.verifying_key().to_bytes()),
937 Bytes32::from(s1.verifying_key().to_bytes())
938 ],
939 name_state.public_keys
940 );
941 assert_eq!(None, name_state.next_public_keys);
942
943 let mut next_name = ns::Name {
945 name: "test".to_string(),
946 sequence: 5,
947 service: ns::Service {
948 code: 0,
949 operations: vec![ns::Operation {
950 subcode: 2,
952 params: ns::Value::from(&ns::PublicKeyParams {
953 public_keys: vec![s3.verifying_key().to_bytes().into()],
954 threshold: None,
955 kind: None,
956 }),
957 }],
958 attesters: None,
959 },
960 signatures: vec![],
961 };
962 next_name
963 .sign(
964 &name_state.public_key_params(),
965 ns::ThresholdLevel::Strict,
966 &[s1.clone(), s2.clone()],
967 )
968 .unwrap();
969
970 next_name.validate().unwrap();
971 let name_state = name_state
972 .verify_the_next(name_state.block_height, name_state.block_time, &next_name)
973 .unwrap();
974 assert!(name_state.next_public_keys.is_some());
975
976 let mut next_name = ns::Name {
977 name: "test".to_string(),
978 sequence: 6,
979 service: ns::Service {
980 code: 0,
981 operations: vec![ns::Operation {
982 subcode: 0,
983 params: ns::Value::Null,
984 }],
985 attesters: None,
986 },
987 signatures: vec![],
988 };
989 next_name
990 .sign(
991 &name_state.public_key_params(),
992 ns::ThresholdLevel::Default,
993 &[s1.clone()],
994 )
995 .unwrap();
996
997 next_name.validate().unwrap();
998 let name_state = name_state
999 .verify_the_next(name_state.block_height, name_state.block_time, &next_name)
1000 .unwrap();
1001 assert_eq!(6, name_state.sequence);
1002 assert_eq!(1, name_state.threshold);
1003 assert_eq!(
1004 vec![
1005 Bytes32::from(s2.verifying_key().to_bytes()),
1006 Bytes32::from(s1.verifying_key().to_bytes())
1007 ],
1008 name_state.public_keys
1009 );
1010 assert_eq!(None, name_state.next_public_keys);
1011
1012 let mut next_name = ns::Name {
1014 name: "test".to_string(),
1015 sequence: 7,
1016 service: ns::Service {
1017 code: 0,
1018 operations: vec![ns::Operation {
1019 subcode: 2,
1021 params: ns::Value::from(&ns::PublicKeyParams {
1022 public_keys: vec![s3.verifying_key().to_bytes().into()],
1023 threshold: None,
1024 kind: None,
1025 }),
1026 }],
1027 attesters: None,
1028 },
1029 signatures: vec![],
1030 };
1031 next_name
1032 .sign(
1033 &name_state.public_key_params(),
1034 ns::ThresholdLevel::Strict,
1035 &[s2.clone(), s1.clone()],
1036 )
1037 .unwrap();
1038
1039 next_name.validate().unwrap();
1040 let name_state = name_state
1041 .verify_the_next(name_state.block_height, name_state.block_time, &next_name)
1042 .unwrap();
1043 assert!(name_state.next_public_keys.is_some());
1044
1045 let mut next_name = ns::Name {
1046 name: "test".to_string(),
1047 sequence: 8,
1048 service: ns::Service {
1049 code: 123,
1050 operations: vec![ns::Operation {
1051 subcode: 0,
1052 params: ns::Value::Null,
1053 }],
1054 attesters: None,
1055 },
1056 signatures: vec![],
1057 };
1058 next_name
1059 .sign(
1060 &name_state.public_key_params(),
1061 ns::ThresholdLevel::Default,
1062 &[s1.clone()],
1063 )
1064 .unwrap();
1065
1066 next_name.validate().unwrap();
1067 let name_state = name_state
1068 .verify_the_next(name_state.block_height, name_state.block_time, &next_name)
1069 .unwrap();
1070 assert_eq!(8, name_state.sequence);
1071 assert_eq!(1, name_state.threshold);
1072 assert_eq!(
1073 vec![
1074 Bytes32::from(s2.verifying_key().to_bytes()),
1075 Bytes32::from(s1.verifying_key().to_bytes())
1076 ],
1077 name_state.public_keys
1078 );
1079 assert_eq!(None, name_state.next_public_keys);
1080
1081 let mut data: Vec<u8> = Vec::new();
1082 into_writer(&name_state, &mut data).unwrap();
1083 println!("name_state: {:?}", hex::encode(&data));
1084 }
1085
1086 #[test]
1087 fn service_state_works() {
1088 let mut service_state = ServiceState {
1089 name: "test".to_string(),
1090 code: 0,
1091 sequence: 0,
1092 data: Vec::new(),
1093 };
1094 let next_name = ns::Name {
1095 name: "test".to_string(),
1096 sequence: 1,
1097 service: ns::Service {
1098 code: 0,
1099 operations: vec![ns::Operation {
1100 subcode: 0,
1101 params: ns::Value::Null,
1102 }],
1103 attesters: None,
1104 },
1105 signatures: vec![],
1106 };
1107
1108 service_state = service_state.verify_the_next(&next_name).unwrap();
1109 assert_eq!(1, service_state.sequence);
1110 assert_eq!(1, service_state.data.len());
1111 assert_eq!(0, service_state.data[0].0);
1112 assert_eq!(ns::Value::Null, service_state.data[0].1);
1113
1114 let next_name = ns::Name {
1115 name: "test".to_string(),
1116 sequence: 2,
1117 service: ns::Service {
1118 code: 0,
1119 operations: vec![ns::Operation {
1120 subcode: 0,
1121 params: ns::Value::Text("hello".to_string()),
1122 }],
1123 attesters: None,
1124 },
1125 signatures: vec![],
1126 };
1127
1128 service_state = service_state.verify_the_next(&next_name).unwrap();
1129 assert_eq!(2, service_state.sequence);
1130 assert_eq!(1, service_state.data.len());
1131 assert_eq!(0, service_state.data[0].0);
1132 assert_eq!(
1133 ns::Value::Text("hello".to_string()),
1134 service_state.data[0].1
1135 );
1136
1137 let next_name = ns::Name {
1138 name: "test".to_string(),
1139 sequence: 3,
1140 service: ns::Service {
1141 code: 0,
1142 operations: vec![ns::Operation {
1143 subcode: 3,
1144 params: ns::Value::Null,
1145 }],
1146 attesters: None,
1147 },
1148 signatures: vec![],
1149 };
1150
1151 service_state = service_state.verify_the_next(&next_name).unwrap();
1152 assert_eq!(3, service_state.sequence);
1153 assert_eq!(2, service_state.data.len());
1154 assert_eq!(0, service_state.data[0].0);
1155 assert_eq!(
1156 ns::Value::Text("hello".to_string()),
1157 service_state.data[0].1
1158 );
1159 assert_eq!(3, service_state.data[1].0);
1160 assert_eq!(ns::Value::Null, service_state.data[1].1);
1161
1162 let next_name = ns::Name {
1163 name: "test".to_string(),
1164 sequence: 4,
1165 service: ns::Service {
1166 code: 0,
1167 operations: vec![ns::Operation {
1168 subcode: 2,
1169 params: ns::Value::Text("hello2".to_string()),
1170 }],
1171 attesters: None,
1172 },
1173 signatures: vec![],
1174 };
1175
1176 service_state = service_state.verify_the_next(&next_name).unwrap();
1177 assert_eq!(4, service_state.sequence);
1178 assert_eq!(3, service_state.data.len());
1179 assert_eq!(0, service_state.data[0].0);
1180 assert_eq!(
1181 ns::Value::Text("hello".to_string()),
1182 service_state.data[0].1
1183 );
1184 assert_eq!(2, service_state.data[1].0);
1185 assert_eq!(
1186 ns::Value::Text("hello2".to_string()),
1187 service_state.data[1].1
1188 );
1189 assert_eq!(3, service_state.data[2].0);
1190 assert_eq!(ns::Value::Null, service_state.data[2].1);
1191 }
1192}