ns_protocol/
state.rs

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
10// After the silence period exceeds 365 days, the name is invalid, the application validation signature should be invalid, and the original registrant can activate the name with any update.
11pub const NAME_STALE_SECONDS: u64 = 60 * 60 * 24 * 365;
12// After the silence period exceeds 365 + 180 days, others are allowed to re-register the name, if no one registers, the original registrant can activate the name with any update
13pub 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        // next name must be validated by Name::validate.
114        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        // handle the `0` service code (Name service)
142        let mut next_state = self.clone();
143        if next.service.operations.len() == 1 && next.service.operations[0].subcode == 0 {
144            // This is the lightweight update operation
145            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                    // allows updates to next public_keys
161                    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                    // update public_keys
177                    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        // next name must be validated by Name::validate.
293        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                // default to replace operation
320                // we should support other operations in the future
321                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        // ToDO: protocol should be parsed as a CBOR Schema
418        match self.code {
419            0 => {
420                // Native Name service, will be handled in NameState::verify_the_next
421                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        // update public_keys in one call
840        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        // update public_keys after NAME_EXPIRE_SECONDS
898        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        // the lightweight update operation
944        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                    // this operation will be overwritten
951                    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        // the other update operation
1013        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                    // this operation will be overwritten
1020                    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}