]> Git Repo - VerusCoin.git/blame - src/pbaas/vdxf.cpp
Build fix
[VerusCoin.git] / src / pbaas / vdxf.cpp
CommitLineData
a88b514e 1/********************************************************************
2 * (C) 2020 Michael Toutonghi
3 *
4 * Distributed under the MIT software license, see the accompanying
5 * file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 *
7 * Support for the Verus Data Exchange Format (VDXF)
8 *
9 */
10
11#include "vdxf.h"
7c8e5e18 12#include "crosschainrpc.h"
a88b514e 13
c8c684e9 14std::string CVDXF::DATA_KEY_SEPARATOR = "::";
15std::map<uint160,std::pair<std::pair<uint32_t, uint32_t>,std::pair<uint32_t, uint32_t>>> CVDXF::VDXF_TYPES;
16uint160 CVDXF::STRUCTURED_DATA_KEY = CVDXF_StructuredData::StructuredDataKey();
17uint160 CVDXF::ZMEMO_MESSAGE_KEY = CVDXF_Data::ZMemoMessageKey();
18uint160 CVDXF::ZMEMO_SIGNATURE_KEY = CVDXF_Data::ZMemoSignatureKey();
a88b514e 19
20std::string TrimLeading(const std::string &Name, unsigned char ch)
21{
22 std::string nameCopy = Name;
23 int removeSpaces;
24 for (removeSpaces = 0; removeSpaces < nameCopy.size(); removeSpaces++)
25 {
26 if (nameCopy[removeSpaces] != ch)
27 {
28 break;
29 }
30 }
31 if (removeSpaces)
32 {
33 nameCopy.erase(nameCopy.begin(), nameCopy.begin() + removeSpaces);
34 }
35 return nameCopy;
36}
37
38std::string TrimTrailing(const std::string &Name, unsigned char ch)
39{
40 std::string nameCopy = Name;
41 int removeSpaces;
42 for (removeSpaces = nameCopy.size() - 1; removeSpaces >= 0; removeSpaces--)
43 {
44 if (nameCopy[removeSpaces] != ch)
45 {
46 break;
47 }
48 }
49 nameCopy.resize(nameCopy.size() - ((nameCopy.size() - 1) - removeSpaces));
50 return nameCopy;
51}
52
53std::string TrimSpaces(const std::string &Name)
54{
55 return TrimTrailing(TrimLeading(Name, ' '), ' ');
56}
57
58// this will add the current Verus chain name to subnames if it is not present
59// on both id and chain names
c8c684e9 60std::vector<std::string> CVDXF::ParseSubNames(const std::string &Name, std::string &ChainOut, bool displayfilter, bool addVerus)
a88b514e 61{
62 std::string nameCopy = Name;
63 std::string invalidChars = "\\/:*?\"<>|";
64 if (displayfilter)
65 {
66 invalidChars += "\n\t\r\b\t\v\f\x1B";
67 }
68 for (int i = 0; i < nameCopy.size(); i++)
69 {
70 if (invalidChars.find(nameCopy[i]) != std::string::npos)
71 {
72 return std::vector<std::string>();
73 }
74 }
75
76 std::vector<std::string> retNames;
77 boost::split(retNames, nameCopy, boost::is_any_of("@"));
78 if (!retNames.size() || retNames.size() > 2)
79 {
80 return std::vector<std::string>();
81 }
82
83 bool explicitChain = false;
7c8e5e18 84 if (retNames.size() == 2 && !retNames[1].empty())
a88b514e 85 {
86 ChainOut = retNames[1];
87 explicitChain = true;
88 }
89
90 nameCopy = retNames[0];
91 boost::split(retNames, nameCopy, boost::is_any_of("."));
92
7c8e5e18 93 if (retNames.size() && retNames.back().empty())
94 {
95 addVerus = false;
96 retNames.pop_back();
97 nameCopy.pop_back();
98 }
99
a88b514e 100 int numRetNames = retNames.size();
101
03bfd9ae 102 std::string verusChainName = boost::to_lower_copy(VERUS_CHAINNAME);
a88b514e 103
104 if (addVerus)
105 {
106 if (explicitChain)
107 {
108 std::vector<std::string> chainOutNames;
109 boost::split(chainOutNames, ChainOut, boost::is_any_of("."));
110 std::string lastChainOut = boost::to_lower_copy(chainOutNames.back());
111
112 if (lastChainOut != "" && lastChainOut != verusChainName)
113 {
114 chainOutNames.push_back(verusChainName);
115 }
116 else if (lastChainOut == "")
117 {
118 chainOutNames.pop_back();
119 }
120 }
121
122 std::string lastRetName = boost::to_lower_copy(retNames.back());
123 if (lastRetName != "" && lastRetName != verusChainName)
124 {
125 retNames.push_back(verusChainName);
126 }
127 else if (lastRetName == "")
128 {
129 retNames.pop_back();
130 }
131 }
132
133 for (int i = 0; i < retNames.size(); i++)
134 {
135 if (retNames[i].size() > KOMODO_ASSETCHAIN_MAXLEN - 1)
136 {
137 retNames[i] = std::string(retNames[i], 0, (KOMODO_ASSETCHAIN_MAXLEN - 1));
138 }
139 // spaces are allowed, but no sub-name can have leading or trailing spaces
140 if (!retNames[i].size() || retNames[i] != TrimTrailing(TrimLeading(retNames[i], ' '), ' '))
141 {
142 return std::vector<std::string>();
143 }
144 }
a88b514e 145 return retNames;
146}
147
148// takes a multipart name, either complete or partially processed with a Parent hash,
149// hash its parent names into a parent ID and return the parent hash and cleaned, single name
150std::string CVDXF::CleanName(const std::string &Name, uint160 &Parent, bool displayfilter)
151{
152 std::string chainName;
153 std::vector<std::string> subNames = ParseSubNames(Name, chainName);
154
155 if (!subNames.size())
156 {
157 return "";
158 }
159
160 if (!Parent.IsNull() &&
161 boost::to_lower_copy(subNames.back()) == boost::to_lower_copy(VERUS_CHAINNAME))
162 {
163 subNames.pop_back();
164 }
165
166 for (int i = subNames.size() - 1; i > 0; i--)
167 {
168 std::string parentNameStr = boost::algorithm::to_lower_copy(subNames[i]);
169 const char *parentName = parentNameStr.c_str();
170 uint256 idHash;
171
172 if (Parent.IsNull())
173 {
174 idHash = Hash(parentName, parentName + parentNameStr.size());
175 }
176 else
177 {
178 idHash = Hash(parentName, parentName + strlen(parentName));
179 idHash = Hash(Parent.begin(), Parent.end(), idHash.begin(), idHash.end());
180 }
181 Parent = Hash160(idHash.begin(), idHash.end());
182 //printf("uint160 for parent %s: %s\n", parentName, Parent.GetHex().c_str());
183 }
184 return subNames[0];
185}
186
187uint160 CVDXF::GetID(const std::string &Name)
188{
189 uint160 parent;
190 std::string cleanName = CleanName(Name, parent);
191
192 std::string subName = boost::algorithm::to_lower_copy(cleanName);
193 const char *idName = subName.c_str();
194 //printf("hashing: %s, %s\n", idName, parent.GetHex().c_str());
195
196 uint256 idHash;
197 if (parent.IsNull())
198 {
199 idHash = Hash(idName, idName + strlen(idName));
200 }
201 else
202 {
203 idHash = Hash(idName, idName + strlen(idName));
204 idHash = Hash(parent.begin(), parent.end(), idHash.begin(), idHash.end());
205
206 }
207 return Hash160(idHash.begin(), idHash.end());
208}
209
210uint160 CVDXF::GetID(const std::string &Name, uint160 &parent)
211{
212 std::string cleanName = CleanName(Name, parent);
213
214 std::string subName = boost::algorithm::to_lower_copy(cleanName);
215 const char *idName = subName.c_str();
216 //printf("hashing: %s, %s\n", idName, parent.GetHex().c_str());
217
218 uint256 idHash;
219 if (parent.IsNull())
220 {
221 idHash = Hash(idName, idName + strlen(idName));
222 }
223 else
224 {
225 idHash = Hash(idName, idName + strlen(idName));
226 idHash = Hash(parent.begin(), parent.end(), idHash.begin(), idHash.end());
227 }
228 return Hash160(idHash.begin(), idHash.end());
229}
230
231// calculate the data key for a name inside of a namespace
232// if the namespace is null, use VERUS_CHAINID
7c8e5e18 233uint160 CVDXF::GetDataKey(const std::string &keyName, uint160 &nameSpaceID)
a88b514e 234{
7c8e5e18 235 std::string keyCopy = keyName;
236 std::vector<std::string> addressParts;
237 boost::split(addressParts, keyCopy, boost::is_any_of(":"));
238
239 // if the first part of the address is a namespace, it is followed by double colon
240 // namespace specifiers have no implicit root
241 if (addressParts.size() > 2 && addressParts[1].empty())
242 {
243 // look up to see if this is the private address of an ID. if not, or if the ID does not have a valid, Sapling address, it is invalid
244 uint160 nsID = DecodeCurrencyName(addressParts[0] + ".");
245 if (!nsID.IsNull())
246 {
247 nameSpaceID = nsID;
248 }
249 keyCopy.clear();
250 for (int i = 2; i < addressParts.size(); i++)
251 {
252 keyCopy = i == 2 ? addressParts[i] : keyCopy + ":" + addressParts[i];
253 }
254 }
255
a88b514e 256 if (nameSpaceID.IsNull())
257 {
258 nameSpaceID = VERUS_CHAINID;
259 }
260 uint160 parent = GetID(DATA_KEY_SEPARATOR, nameSpaceID);
7c8e5e18 261 return GetID(keyCopy, parent);
a88b514e 262}
263
264bool uni_get_bool(UniValue uv, bool def)
265{
266 try
267 {
268 if (uv.isStr())
269 {
270 std::string boolStr;
271 if ((boolStr = uni_get_str(uv, def ? "true" : "false")) == "true" || boolStr == "1")
272 {
273 return true;
274 }
275 else if (boolStr == "false" || boolStr == "0")
276 {
277 return false;
278 }
279 return def;
280 }
281 else if (uv.isNum())
282 {
283 return uv.get_int() != 0;
284 }
285 else
286 {
287 return uv.get_bool();
288 }
289 return false;
290 }
291 catch(const std::exception& e)
292 {
293 return def;
294 }
295}
296
297int32_t uni_get_int(UniValue uv, int32_t def)
298{
299 try
300 {
54f68f98 301 if (!uv.isStr() && !uv.isNum())
4c26b35c 302 {
54f68f98 303 return def;
4c26b35c 304 }
54f68f98 305 return (uv.isStr() ? atoi(uv.get_str()) : atoi(uv.getValStr()));
a88b514e 306 }
307 catch(const std::exception& e)
308 {
309 return def;
310 }
311}
312
313int64_t uni_get_int64(UniValue uv, int64_t def)
314{
315 try
316 {
54f68f98 317 if (!uv.isStr() && !uv.isNum())
4c26b35c 318 {
54f68f98 319 return def;
4c26b35c 320 }
54f68f98 321 return (uv.isStr() ? atoi64(uv.get_str()) : atoi64(uv.getValStr()));
a88b514e 322 }
323 catch(const std::exception& e)
324 {
325 return def;
326 }
327}
328
329std::string uni_get_str(UniValue uv, std::string def)
330{
331 try
332 {
333 return uv.get_str();
334 }
335 catch(const std::exception& e)
336 {
337 return def;
338 }
339}
340
341std::vector<UniValue> uni_getValues(UniValue uv, std::vector<UniValue> def)
342{
343 try
344 {
345 return uv.getValues();
346 }
347 catch(const std::exception& e)
348 {
349 return def;
350 }
351}
352
c8c684e9 353// this deserializes a vector into either a VDXF data object or a VDXF structured
354// object, which may contain one or more VDXF data objects.
355// If the data in the sourceVector is not a recognized VDXF object, the returned
356// variant will be empty/invalid, otherwise, it will be a recognized VDXF object
357// or a VDXF structured object containing one or more recognized VDXF objects.
358VDXFData DeserializeVDXFData(const std::vector<unsigned char> &sourceVector)
359{
360 CVDXF_StructuredData sData;
361 ::FromVector(sourceVector, sData);
362 if (sData.IsValid())
363 {
364 return sData;
365 }
366 else
367 {
368 CVDXF_Data Data;
369 ::FromVector(sourceVector, sData);
370 if (Data.IsValid())
371 {
372 return Data;
373 }
374 }
375 return VDXFData();
376}
377
378std::vector<unsigned char> SerializeVDXFData(const VDXFData &vdxfData)
379{
380 return boost::apply_visitor(CSerializeVDXFData(), vdxfData);
381}
382
This page took 0.095211 seconds and 4 git commands to generate.