1 module tagion.basic.ConsensusExceptions;
2 
3 @safe:
4 
5 import std.format : format;
6 import tagion.basic.tagionexceptions : TagionException;
7 
8 void Check(E)(bool flag, ConsensusFailCode code, string file = __FILE__, size_t line = __LINE__) pure
9 if (is(E : ConsensusException)) {
10     if (!flag) {
11         throw new E(code, file, line);
12     }
13 }
14 
15 enum ConsensusFailCode {
16     NONE,
17     NO_MOTHER,
18     MOTHER_AND_FATHER_SAME_SIZE,
19     MOTHER_AND_FATHER_CAN_NOT_BE_THE_SAME,
20     // PACKAGE_SIZE_OVERFLOW,
21     // EVENT_PACKAGE_MISSING_PUBLIC_KEY,
22     // EVENT_PACKAGE_MISSING_EVENT,
23     // EVENT_PACKAGE_BAD_SIGNATURE,
24     EVENT_NODE_ID_UNKNOWN,
25     EVENT_BAD_SIGNATURE,
26     EVENT_NOT_FOUND,
27     EVENT_FATHER_FORK,
28     EVENT_MOTHER_FORK,
29     EVENT_MOTHER_LESS,
30     EVENT_MOTHER_CHANNEL,
31     EVENT_MOTHER_GROUNDED,
32     EVENT_FATHER_GROUNDED,
33     EVENT_PHONY_EVA,
34     EVENT_ALTITUDE,
35     EVENT_MISSING_IN_CACHE,
36     EVENT_MISSING_PUBKEY,
37     EVENT_MISSING_SIGNATURE,
38 
39     HASHGRAPH_EVENT_INITIALIZE,
40     HASHGRAPH_EVENT_INITIALIZE_SIZE,
41     HASHGRAPH_DUBLICATE_WITNESS,
42 
43     GOSSIPNET_EVENT_HAS_BEEN_CACHED,
44     GOSSIPNET_ILLEGAL_EXCHANGE_STATE,
45     GOSSIPNET_EXPECTED_EXCHANGE_STATE,
46     GOSSIPNET_EXPECTED_OR_EXCHANGE_STATE,
47     GOSSIPNET_EXPECTED_3_EXCHANGE_STATE,
48     //    GOSSIPNET_BAD_EXCHNAGE_STATE,
49     GOSSIPNET_REPLICATED_PUBKEY,
50     GOSSIPNET_EVENTPACKAGE_NOT_FOUND,
51     GOSSIPNET_MISSING_EVENTS,
52     GOSSIPNET_TIDAL_WAVE_CONTAINS_EVENTS,
53     GOSSIPNET_ILLEGAL_CHANNEL,
54     GOSSIPNET_FIRST_EVENT_MUST_BE_EVA,
55     //    EVENT_MISSING_BODY,
56 
57     SECURITY_SIGN_FAULT,
58     SECURITY_PUBLIC_KEY_CREATE_FAULT,
59     SECURITY_PUBLIC_KEY_PARSE_FAULT,
60     // SECURITY_DER_SIGNATURE_PARSE_FAULT,
61     SECURITY_COMPACT_SIGNATURE_PARSE_FAULT,
62     SECURITY_SIGNATURE_SIZE_FAULT,
63 
64     SECURITY_PRIVATE_KEY_TWEAK_ADD_FAULT,
65     SECURITY_PRIVATE_KEY_TWEAK_MULT_FAULT,
66     SECURITY_PUBLIC_KEY_TWEAK_ADD_FAULT,
67     SECURITY_PUBLIC_KEY_TWEAK_MULT_FAULT,
68     SECURITY_PUBLIC_KEY_COMPRESS_SIZE_FAULT,
69     SECURITY_PUBLIC_KEY_UNCOMPRESS_SIZE_FAULT,
70     SECURITY_PUBLIC_KEY_SERIALIZE,
71     SECURITY_PUBLIC_KEY_AGGREGATE,
72     SECURITY_PRIVATE_KEY_INVALID,
73     SECURITY_PUBKEY_KEY_INVALID,
74 
75     SECURITY_FAILD_TO_CREATE_KEYPAIR,
76     SECURITY_FAILD_TO_SIGN_MESSAGE,
77     SECURITY_FAILD_PUBKEY_FROM_KEYPAIR,
78     SECURITY_EDCH_FAULT,
79 
80     SECURITY_MASK_VECTOR_IS_ZERO,
81     SECURITY_MESSAGE_HASH_KEY,
82 
83     CIPHER_DECRYPT_CRC_ERROR,
84     CIPHER_DECRYPT_ERROR,
85 
86     DART_ARCHIVE_ALREADY_ADDED,
87     DART_ARCHIVE_DOES_NOT_EXIST,
88     DART_ARCHIVE_SECTOR_NOT_FOUND,
89 
90     NETWORK_BAD_PACKAGE_TYPE,
91 
92     SCRIPTING_ENGINE_HiBON_FORMAT_FAULT,
93     SCRIPTING_ENGINE_DATA_VALIDATION_FAULT,
94     SCRIPTING_ENGINE_SIGNATUR_FAULT,
95 
96     SMARTSCRIPT_NO_SIGNATURE,
97     SMARTSCRIPT_MISSING_SIGNATURE_OR_INPUTS,
98     SMARTSCRIPT_FINGERS_OR_INPUTS_MISSING,
99     SMARTSCRIPT_FINGERPRINT_DOES_NOT_MATCH_INPUT,
100     SMARTSCRIPT_INPUT_NOT_SIGNED_CORRECTLY,
101     SMARTSCRIPT_NOT_ENOUGH_MONEY,
102     SMARTSCRIPT_CAUGHT_TAGIONEXCEPTION,
103     SMARTSCRIPT_CAUGHT_EXCEPTION,
104     SMARTSCRIPT_CAUGHT_SMARTSCRIPTEXCEPTION,
105     SMARTSCRIPT_NO_OUTPUT,
106     SMARTSCRIPT_INVALID_OUTPUT
107 
108 }
109 
110 class ConsensusException : TagionException {
111     immutable ConsensusFailCode code;
112     this(string msg, ConsensusFailCode code = ConsensusFailCode.NONE,
113             string file = __FILE__, size_t line = __LINE__) pure {
114         this.code = code;
115         super(msg, file, line);
116     }
117 
118     this(ConsensusFailCode code, string file = __FILE__, size_t line = __LINE__) pure {
119         super(consensus_error_messages[code], file, line);
120         this.code = code;
121     }
122 }
123 
124 class EventConsensusException : GossipConsensusException {
125     this(ConsensusFailCode code, string file = __FILE__, size_t line = __LINE__) pure {
126         super(code, file, line);
127     }
128 }
129 
130 class SecurityConsensusException : ConsensusException {
131     this(ConsensusFailCode code, string file = __FILE__, size_t line = __LINE__) pure {
132         super(code, file, line);
133     }
134 }
135 
136 class GossipConsensusException : ConsensusException {
137     this(ConsensusFailCode code, string file = __FILE__, size_t line = __LINE__) pure {
138         super(code, file, line);
139     }
140 
141     this(string msg, ConsensusFailCode code, string file = __FILE__, size_t line = __LINE__) pure {
142         super(msg, code, file, line);
143     }
144 }
145 
146 class HashGraphConsensusException : EventConsensusException {
147     this(ConsensusFailCode code, string file = __FILE__, size_t line = __LINE__) pure {
148         super(code, file, line);
149     }
150 }
151 
152 class DARTConsensusException : ConsensusException {
153     this(ConsensusFailCode code, string file = __FILE__, size_t line = __LINE__) pure {
154         super(code, file, line);
155     }
156 }
157 
158 class ScriptingEngineConsensusException : ConsensusException {
159     this(ConsensusFailCode code, string file = __FILE__, size_t line = __LINE__) pure {
160         super(code, file, line);
161     }
162 }
163 
164 class SSLSocketFiberConsensusException : ConsensusException {
165     this(ConsensusFailCode code, string file = __FILE__, size_t line = __LINE__) pure {
166         super(code, file, line);
167     }
168 }
169 
170 class SocketFiberConsensusException : ConsensusException {
171     this(ConsensusFailCode code, string file = __FILE__, size_t line = __LINE__) pure {
172         super(code, file, line);
173     }
174 }
175 
176 class SmartScriptException : ConsensusException {
177     this(ConsensusFailCode code, string file = __FILE__, size_t line = __LINE__) pure {
178         super(code, file, line);
179     }
180 }
181 
182 shared static this() {
183     with (ConsensusFailCode) {
184         // dfmt off
185         consensus_error_messages = [
186             NONE                                        : "None",
187             NO_MOTHER                                   : "If an event has no mother it can not have a father",
188             MOTHER_AND_FATHER_SAME_SIZE                 : "Mother and Father must user the same hash function",
189             MOTHER_AND_FATHER_CAN_NOT_BE_THE_SAME       : "The mother and father can not be the same event",
190 
191             EVENT_NODE_ID_UNKNOWN                       : "Public key is not mapped to a Node ID",
192             EVENT_BAD_SIGNATURE                         : "Bad signature for event",
193             EVENT_NOT_FOUND                             : "Event not found",
194             EVENT_MOTHER_FORK                           : "Event mother fork",
195             EVENT_FATHER_FORK                           : "Event father fork",
196             EVENT_MOTHER_LESS                           : "Event is mother less",
197             EVENT_MOTHER_CHANNEL                        : "Event should be on the same channel as the mother",
198             EVENT_MOTHER_GROUNDED                       : "Mother can't be accessed becuase this event is dead",
199             EVENT_FATHER_GROUNDED                       : "Father can't be accessed becuase this event is dead",
200             EVENT_PHONY_EVA                             : "Event already exist's for this node",
201             EVENT_ALTITUDE                              : "The Event's altitude must increase by one from mother to daughter",
202             EVENT_MISSING_IN_CACHE                      : "Event missing in the cache",
203             EVENT_MISSING_PUBKEY                        : "Pubkey missing in Event",
204             EVENT_MISSING_SIGNATURE                     : "Signature missing in Event",
205 
206             HASHGRAPH_EVENT_INITIALIZE                  : "Majority of events must be witnesses to initialize the network",
207             HASHGRAPH_EVENT_INITIALIZE_SIZE             : "Number of events in coherent wavefront is too large",
208             HASHGRAPH_DUBLICATE_WITNESS                 : "Only one witness per node is alowes for a coherent wavefront",
209 
210 //            EVENT_MISSING_BODY                        : "Event is missing eventbody",
211 
212             GOSSIPNET_EVENT_HAS_BEEN_CACHED             : "Gossip net has already cached event",
213             GOSSIPNET_ILLEGAL_EXCHANGE_STATE            : "Gossip exchange state is illegal %s",
214             GOSSIPNET_EXPECTED_EXCHANGE_STATE           : "Gossip exchange state is illegal %s expected %s",
215             GOSSIPNET_EXPECTED_OR_EXCHANGE_STATE        : "Gossip exchange state is illegal %s expected %s or %s",
216             GOSSIPNET_EXPECTED_3_EXCHANGE_STATE         : "Gossip exchange state is illegal %s expected %s, %s or %s",
217             GOSSIPNET_REPLICATED_PUBKEY                 : "The public key of the received package is the same as the nodes public key",
218             GOSSIPNET_EVENTPACKAGE_NOT_FOUND            : "Event package not found in the event package cache",
219             GOSSIPNET_MISSING_EVENTS                    : "Gossip network missing events",
220             GOSSIPNET_TIDAL_WAVE_CONTAINS_EVENTS        : "Tidal wave should not contain events",
221             GOSSIPNET_ILLEGAL_CHANNEL                   : "Gossip channel not valid",
222             GOSSIPNET_FIRST_EVENT_MUST_BE_EVA           : "First event send in a ripple wavefront must be an Eva event",
223 
224             SECURITY_SIGN_FAULT                         : "Sign of message failed",
225             SECURITY_PUBLIC_KEY_CREATE_FAULT            : "Failed to create public key",
226             SECURITY_PUBLIC_KEY_PARSE_FAULT             : "Failed to parse public key",
227             SECURITY_PUBLIC_KEY_AGGREGATE               : "Failed to aggregate public key",             
228         //SECURITY_DER_SIGNATURE_PARSE_FAULT          : "Failed to parse DER signature",
229             SECURITY_COMPACT_SIGNATURE_PARSE_FAULT      : "Failed to parse Compact signature",
230             SECURITY_SIGNATURE_SIZE_FAULT               : "The size of the signature is wrong",
231 
232             SECURITY_PUBLIC_KEY_COMPRESS_SIZE_FAULT     : "Wrong size of compressed Public key",
233             SECURITY_PUBLIC_KEY_UNCOMPRESS_SIZE_FAULT   : "Wrong size of uncompressed Public key",
234             SECURITY_PUBLIC_KEY_SERIALIZE               : "Unable to serialize public key",
235 
236             SECURITY_EDCH_FAULT                         : "EDCH failed",
237 
238             SECURITY_PRIVATE_KEY_TWEAK_ADD_FAULT        : "Failed to tweak add private key",
239             SECURITY_PRIVATE_KEY_TWEAK_MULT_FAULT       : "Failed to tweak mult private key",
240             SECURITY_PUBLIC_KEY_TWEAK_ADD_FAULT         : "Failed to tweak add public key",
241             SECURITY_PUBLIC_KEY_TWEAK_MULT_FAULT        : "Failed to tweak mult public key",
242             SECURITY_PRIVATE_KEY_INVALID                : "Invalid private key",
243             SECURITY_PUBKEY_KEY_INVALID                 : "Invalid pubkey key",
244             
245             SECURITY_FAILD_TO_CREATE_KEYPAIR            : "Faild to create keypair",
246             SECURITY_FAILD_TO_SIGN_MESSAGE              : "Faild to sign message",
247             SECURITY_FAILD_PUBKEY_FROM_KEYPAIR          : "Faild to procude pubkey from keypair",
248             SECURITY_MASK_VECTOR_IS_ZERO                : "Mask vector must be different from zero",
249             SECURITY_MESSAGE_HASH_KEY                   : "A message containg a hash-kye can not be signed",
250 
251             CIPHER_DECRYPT_CRC_ERROR                    : "Decrypt CRC checksum failure",
252             CIPHER_DECRYPT_ERROR                        : "Decrypt failure",
253 
254             DART_ARCHIVE_ALREADY_ADDED                  : "DART Failed archive is already added",
255             DART_ARCHIVE_DOES_NOT_EXIST                 : "DART Failed archive does not exist",
256             DART_ARCHIVE_SECTOR_NOT_FOUND               : "DART Failed sector is not maintained by this node",
257             NETWORK_BAD_PACKAGE_TYPE                    : "Illegal package type",
258 
259             SCRIPTING_ENGINE_HiBON_FORMAT_FAULT         : "The data is not a HiBON format",
260             SCRIPTING_ENGINE_DATA_VALIDATION_FAULT      : "Transaction object does not contain the right elements",
261             SCRIPTING_ENGINE_SIGNATUR_FAULT             : "Signatures are not correct",
262 
263             SMARTSCRIPT_NO_SIGNATURE                    : "Smart script does not contain enought signatures",
264             SMARTSCRIPT_MISSING_SIGNATURE_OR_INPUTS     : "Smart script is missing some signatures for some inputs",
265             SMARTSCRIPT_FINGERS_OR_INPUTS_MISSING       : "Smart script number of input figerprints does not match the number of inputs",
266             SMARTSCRIPT_FINGERPRINT_DOES_NOT_MATCH_INPUT: "Smart script fingerprint does not match the input",
267             SMARTSCRIPT_INPUT_NOT_SIGNED_CORRECTLY      : "Smart script one of the input has a wrong signature",
268             SMARTSCRIPT_NOT_ENOUGH_MONEY                : "Smart script not enough money in the account",
269             SMARTSCRIPT_CAUGHT_TAGIONEXCEPTION          : "Invalid smart script caught a Tagionexception",
270             SMARTSCRIPT_CAUGHT_EXCEPTION                : "Invalid smart script caught an Exception",
271             SMARTSCRIPT_CAUGHT_SMARTSCRIPTEXCEPTION     : "Invalid smart script caught an SmartScriptException",
272             SMARTSCRIPT_NO_OUTPUT                       : "Smart script does not contain any outputs",
273             SMARTSCRIPT_INVALID_OUTPUT                  : "Input currency value is less then output value"
274             ];
275         // dfmt on
276     }
277 }
278 
279 static immutable(string[ConsensusFailCode]) consensus_error_messages;
280 
281 @safe template consensusCheck(Consensus) {
282     static if (is(Consensus : ConsensusException)) {
283         void consensusCheck(bool flag, ConsensusFailCode code,
284                 string file = __FILE__, size_t line = __LINE__) pure {
285             if (!flag) {
286                 throw new Consensus(code, file, line);
287             }
288         }
289     }
290     else {
291         static assert(0, "Type " ~ Consensus.stringof ~ " not supported");
292     }
293 }
294 
295 @safe template consensusCheckArguments(Consensus) {
296     static if (is(Consensus : ConsensusException)) {
297         ref auto consensusCheckArguments(A...)(A args) pure {
298             struct Arguments {
299                 A args;
300                 void check(bool flag, ConsensusFailCode code,
301                         string file = __FILE__, size_t line = __LINE__) const {
302                     if (!flag) {
303                         immutable msg = format(consensus_error_messages[code], args);
304                         throw new Consensus(msg, code, file, line);
305                     }
306                 }
307             }
308 
309             return const(Arguments)(args);
310         }
311     }
312     else {
313         static assert(0, "Type " ~ Consensus.stringof ~ " not supported");
314     }
315 }
316 
317 @safe template convertEnum(Enum, Consensus) {
318     const(Enum) convertEnum(uint enum_number, string file = __FILE__, size_t line = __LINE__) pure {
319         if (enum_number <= Enum.max) {
320             return cast(Enum) enum_number;
321         }
322         throw new Consensus(ConsensusFailCode.NETWORK_BAD_PACKAGE_TYPE, file, line);
323         assert(0);
324     }
325 }