ant_protocol/storage/
pointer.rs1use crate::storage::{ChunkAddress, GraphEntryAddress, PointerAddress, ScratchpadAddress};
10use bls::{PublicKey, SecretKey, Signature};
11use serde::{Deserialize, Serialize};
12use xor_name::XorName;
13
14#[derive(Clone, Serialize, Deserialize, PartialEq, Eq, Ord, PartialOrd)]
17pub struct Pointer {
18 owner: PublicKey,
19 counter: u32,
20 target: PointerTarget,
21 signature: Signature,
22}
23
24impl std::fmt::Debug for Pointer {
25 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26 f.debug_struct("Pointer")
27 .field("owner", &self.owner.to_hex())
28 .field("counter", &self.counter)
29 .field("target", &self.target)
30 .field("signature", &hex::encode(self.signature.to_bytes()))
31 .finish()
32 }
33}
34
35#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Ord, PartialOrd)]
37pub enum PointerTarget {
38 ChunkAddress(ChunkAddress),
39 GraphEntryAddress(GraphEntryAddress),
40 PointerAddress(PointerAddress),
41 ScratchpadAddress(ScratchpadAddress),
42}
43
44impl PointerTarget {
45 pub fn xorname(&self) -> XorName {
47 match self {
48 PointerTarget::ChunkAddress(addr) => *addr.xorname(),
49 PointerTarget::GraphEntryAddress(addr) => addr.xorname(),
50 PointerTarget::PointerAddress(addr) => addr.xorname(),
51 PointerTarget::ScratchpadAddress(addr) => addr.xorname(),
52 }
53 }
54
55 pub fn to_hex(&self) -> String {
57 match self {
58 PointerTarget::ChunkAddress(addr) => addr.to_hex(),
59 PointerTarget::GraphEntryAddress(addr) => addr.to_hex(),
60 PointerTarget::PointerAddress(addr) => addr.to_hex(),
61 PointerTarget::ScratchpadAddress(addr) => addr.to_hex(),
62 }
63 }
64}
65
66impl Pointer {
67 pub fn new(owner: &SecretKey, counter: u32, target: PointerTarget) -> Self {
71 let pubkey = owner.public_key();
72 let bytes_to_sign = Self::bytes_to_sign(&pubkey, counter, &target);
73 let signature = owner.sign(&bytes_to_sign);
74
75 Self {
76 owner: pubkey,
77 counter,
78 target,
79 signature,
80 }
81 }
82
83 pub fn new_with_signature(
85 owner: PublicKey,
86 counter: u32,
87 target: PointerTarget,
88 signature: Signature,
89 ) -> Self {
90 Self {
91 owner,
92 counter,
93 target,
94 signature,
95 }
96 }
97
98 fn bytes_to_sign(owner: &PublicKey, counter: u32, target: &PointerTarget) -> Vec<u8> {
100 let mut bytes = Vec::new();
101 bytes.extend_from_slice(&owner.to_bytes());
103 bytes.extend_from_slice(&counter.to_le_bytes());
105 if let Ok(target_bytes) = rmp_serde::to_vec(target) {
107 bytes.extend_from_slice(&target_bytes);
108 }
109 bytes
110 }
111
112 pub fn address(&self) -> PointerAddress {
114 PointerAddress::new(self.owner)
115 }
116
117 pub fn owner(&self) -> &PublicKey {
119 &self.owner
120 }
121
122 pub fn target(&self) -> &PointerTarget {
124 &self.target
125 }
126
127 pub fn bytes_for_signature(&self) -> Vec<u8> {
129 Self::bytes_to_sign(&self.owner, self.counter, &self.target)
130 }
131
132 pub fn xorname(&self) -> XorName {
133 self.address().xorname()
134 }
135
136 pub fn counter(&self) -> u32 {
139 self.counter
140 }
141
142 pub fn verify_signature(&self) -> bool {
144 let bytes = self.bytes_for_signature();
145 self.owner.verify(&self.signature, &bytes)
146 }
147
148 pub fn size() -> usize {
150 size_of::<Pointer>()
151 }
152}
153
154#[cfg(test)]
155mod tests {
156 use super::*;
157
158 #[test]
159 fn test_pointer_creation_and_validation() {
160 let owner_sk = SecretKey::random();
161 let counter = 1;
162 let pk = SecretKey::random().public_key();
163 let target = PointerTarget::GraphEntryAddress(GraphEntryAddress::new(pk));
164
165 let pointer = Pointer::new(&owner_sk, counter, target.clone());
167 assert!(pointer.verify_signature()); let wrong_sk = SecretKey::random();
171 let sig = wrong_sk.sign(pointer.bytes_for_signature());
172 let wrong_pointer =
173 Pointer::new_with_signature(owner_sk.public_key(), counter, target.clone(), sig);
174 assert!(!wrong_pointer.verify_signature()); }
176}