/ src / error.rs
error.rs
  1  /* This file is part of DarkFi (https://dark.fi)
  2   *
  3   * Copyright (C) 2020-2025 Dyne.org foundation
  4   *
  5   * This program is free software: you can redistribute it and/or modify
  6   * it under the terms of the GNU Affero General Public License as
  7   * published by the Free Software Foundation, either version 3 of the
  8   * License, or (at your option) any later version.
  9   *
 10   * This program is distributed in the hope that it will be useful,
 11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
 12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13   * GNU Affero General Public License for more details.
 14   *
 15   * You should have received a copy of the GNU Affero General Public License
 16   * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 17   */
 18  
 19  // Hello developer. Please add your error to the according subsection
 20  // that is commented, or make a new subsection. Keep it clean.
 21  
 22  /// Main result type used throughout the codebase.
 23  pub type Result<T> = std::result::Result<T, Error>;
 24  
 25  /// Result type used in the Client module
 26  pub type ClientResult<T> = std::result::Result<T, ClientFailed>;
 27  
 28  /// General library errors used throughout the codebase.
 29  #[derive(Debug, Clone, thiserror::Error)]
 30  pub enum Error {
 31      // ==============
 32      // Parsing errors
 33      // ==============
 34      #[error("Parse failed: {0}")]
 35      ParseFailed(&'static str),
 36  
 37      #[error(transparent)]
 38      ParseIntError(#[from] std::num::ParseIntError),
 39  
 40      #[error(transparent)]
 41      ParseFloatError(#[from] std::num::ParseFloatError),
 42  
 43      #[cfg(feature = "url")]
 44      #[error(transparent)]
 45      UrlParseError(#[from] url::ParseError),
 46  
 47      #[error("URL parse error: {0}")]
 48      UrlParse(String),
 49  
 50      #[error(transparent)]
 51      AddrParseError(#[from] std::net::AddrParseError),
 52  
 53      #[error("Could not parse token parameter")]
 54      TokenParseError,
 55  
 56      #[error(transparent)]
 57      TryFromSliceError(#[from] std::array::TryFromSliceError),
 58  
 59      #[cfg(feature = "semver")]
 60      #[error("semver parse error: {0}")]
 61      SemverError(String),
 62  
 63      // ===============
 64      // Encoding errors
 65      // ===============
 66      #[error("decode failed: {0}")]
 67      DecodeError(&'static str),
 68  
 69      #[error("encode failed: {0}")]
 70      EncodeError(&'static str),
 71  
 72      #[error("VarInt was encoded in a non-minimal way")]
 73      NonMinimalVarInt,
 74  
 75      #[error(transparent)]
 76      Utf8Error(#[from] std::string::FromUtf8Error),
 77  
 78      #[error(transparent)]
 79      StrUtf8Error(#[from] std::str::Utf8Error),
 80  
 81      #[cfg(feature = "tinyjson")]
 82      #[error("JSON parse error: {0}")]
 83      JsonParseError(String),
 84  
 85      #[cfg(feature = "tinyjson")]
 86      #[error("JSON generate error: {0}")]
 87      JsonGenerateError(String),
 88  
 89      #[cfg(feature = "toml")]
 90      #[error(transparent)]
 91      TomlDeserializeError(#[from] toml::de::Error),
 92  
 93      #[cfg(feature = "bs58")]
 94      #[error(transparent)]
 95      Bs58DecodeError(#[from] bs58::decode::Error),
 96  
 97      #[error("Bad operation type byte")]
 98      BadOperationType,
 99  
100      // ======================
101      // Network-related errors
102      // ======================
103      #[error("Invalid Dialer scheme")]
104      InvalidDialerScheme,
105  
106      #[error("Invalid Listener scheme")]
107      InvalidListenerScheme,
108  
109      #[error("Unsupported network transport: {0}")]
110      UnsupportedTransport(String),
111  
112      #[error("Unsupported network transport upgrade: {0}")]
113      UnsupportedTransportUpgrade(String),
114  
115      #[error("Transport request exceeds number of accepted transports")]
116      InvalidTransportRequest,
117  
118      #[error("Connection failed: {0}")]
119      ConnectFailed(String),
120  
121      #[cfg(feature = "system")]
122      #[error(transparent)]
123      TimeoutError(#[from] crate::system::timeout::TimeoutError),
124  
125      #[error("Connection timed out")]
126      ConnectTimeout,
127  
128      #[error("Channel stopped")]
129      ChannelStopped,
130  
131      #[error("Channel timed out")]
132      ChannelTimeout,
133  
134      #[error("Failed to reach any seeds")]
135      SeedFailed,
136  
137      #[error("Network service stopped")]
138      NetworkServiceStopped,
139  
140      #[error("Create listener bound to {0} failed")]
141      BindFailed(String),
142  
143      #[error("Accept a new incoming connection from the listener {0} failed")]
144      AcceptConnectionFailed(String),
145  
146      #[error("Accept a new tls connection from the listener {0} failed")]
147      AcceptTlsConnectionFailed(String),
148  
149      #[error("Connector stopped: {0}")]
150      ConnectorStopped(String),
151  
152      #[error("Network operation failed")]
153      NetworkOperationFailed,
154  
155      #[error("Missing P2P message dispatcher")]
156      MissingDispatcher,
157  
158      #[error("P2P message is invalid")]
159      MessageInvalid,
160  
161      #[error("P2P message subsystem over metering limit")]
162      MeteringLimitExceeded,
163  
164      #[cfg(feature = "arti-client")]
165      #[error(transparent)]
166      ArtiError(#[from] arti_client::Error),
167  
168      #[error("Malformed packet")]
169      MalformedPacket,
170  
171      #[error("Error decoding packet: {0}")]
172      DecodePacket(String),
173  
174      #[error("Socks proxy error: {0}")]
175      SocksError(String),
176  
177      #[error("No Socks5 URL found")]
178      NoSocks5UrlFound,
179  
180      #[error("No URL found")]
181      NoUrlFound,
182  
183      #[error("Tor error: {0}")]
184      TorError(String),
185  
186      #[error("Node is not connected to other nodes.")]
187      NetworkNotConnected,
188  
189      #[error("P2P network stopped")]
190      P2PNetworkStopped,
191  
192      #[error("No such host color exists")]
193      InvalidHostColor,
194  
195      #[error("No matching hostlist entry")]
196      HostDoesNotExist,
197  
198      #[error("Invalid state transition: current_state={0}, end_state={1}")]
199      HostStateBlocked(String, String),
200  
201      // =============
202      // Crypto errors
203      // =============
204      #[cfg(feature = "halo2_proofs")]
205      #[error("halo2 plonk error: {0}")]
206      PlonkError(String),
207  
208      #[error("Wrong witness type at index: {0}")]
209      WrongWitnessType(usize),
210  
211      #[error("Wrong witnesses count")]
212      WrongWitnessesCount,
213  
214      #[error("Wrong public inputs count")]
215      WrongPublicInputsCount,
216  
217      #[error("Unable to decrypt mint note: {0}")]
218      NoteDecryptionFailed(String),
219  
220      #[error("No keypair file detected")]
221      KeypairPathNotFound,
222  
223      #[error("Failed converting bytes to PublicKey")]
224      PublicKeyFromBytes,
225  
226      #[error("Failed converting bytes to Coin")]
227      CoinFromBytes,
228  
229      #[error("Failed converting bytes to SecretKey")]
230      SecretKeyFromBytes,
231  
232      #[error("Failed converting b58 string to PublicKey")]
233      PublicKeyFromStr,
234  
235      #[error("Failed converting bs58 string to SecretKey")]
236      SecretKeyFromStr,
237  
238      #[error("Invalid DarkFi address")]
239      InvalidAddress,
240  
241      #[error("unable to decrypt rcpt")]
242      TxRcptDecryptionError,
243  
244      #[cfg(feature = "blake3")]
245      #[error(transparent)]
246      Blake3FromHexError(#[from] blake3::HexError),
247  
248      // =======================
249      // Protocol-related errors
250      // =======================
251      #[error("Unsupported chain")]
252      UnsupportedChain,
253  
254      #[error("JSON-RPC error: {0:?}")]
255      JsonRpcError((i32, String)),
256  
257      #[cfg(feature = "rpc")]
258      #[error(transparent)]
259      RpcServerError(RpcError),
260  
261      #[cfg(feature = "rpc")]
262      #[error("JSON-RPC connections exhausted")]
263      RpcConnectionsExhausted,
264  
265      #[cfg(feature = "rpc")]
266      #[error("JSON-RPC server stopped")]
267      RpcServerStopped,
268  
269      #[cfg(feature = "rpc")]
270      #[error("JSON-RPC client stopped")]
271      RpcClientStopped,
272  
273      #[error("Unexpected JSON-RPC data received: {0}")]
274      UnexpectedJsonRpc(String),
275  
276      #[error("Received proposal from unknown node")]
277      UnknownNodeError,
278  
279      #[error("Public inputs are invalid")]
280      InvalidPublicInputsError,
281  
282      #[error("Signature could not be verified")]
283      InvalidSignature,
284  
285      #[error("State transition failed")]
286      StateTransitionError,
287  
288      #[error("No forks exist")]
289      ForksNotFound,
290  
291      #[error("Check if proposal extends any existing fork chains failed")]
292      ExtendedChainIndexNotFound,
293  
294      #[error("Proposal contains missmatched hashes")]
295      ProposalHashesMissmatchError,
296  
297      #[error("Proposal contains missmatched headers")]
298      ProposalHeadersMissmatchError,
299  
300      #[error("Unable to verify transfer transaction")]
301      TransferTxVerification,
302  
303      #[error("Erroneous transactions detected")]
304      ErroneousTxsDetected,
305  
306      #[error("Proposal task stopped")]
307      ProposalTaskStopped,
308  
309      #[error("Proposal already exists")]
310      ProposalAlreadyExists,
311  
312      #[error("Consensus task stopped")]
313      ConsensusTaskStopped,
314  
315      #[error("Miner task stopped")]
316      MinerTaskStopped,
317  
318      #[error("Garbage collection task stopped")]
319      GarbageCollectionTaskStopped,
320  
321      #[error("Calculated total work is zero")]
322      PoWTotalWorkIsZero,
323  
324      #[error("Erroneous cutoff calculation")]
325      PoWCuttofCalculationError,
326  
327      #[error("Provided timestamp is invalid")]
328      PoWInvalidTimestamp,
329  
330      #[error("Provided output hash is greater than current target")]
331      PoWInvalidOutHash,
332  
333      #[error("Contracts states monotree root missing")]
334      ContractsStatesRootNotFoundError,
335  
336      #[error("Contracts states monotree root missmatch: {0} - {1}")]
337      ContractsStatesRootError(String, String),
338  
339      #[error("Hashing of Monero data failed: {0}")]
340      MoneroHashingError(String),
341  
342      // ===============
343      // Database errors
344      // ===============
345      #[error("Database error: {0}")]
346      DatabaseError(String),
347  
348      #[cfg(feature = "sled-overlay")]
349      #[error(transparent)]
350      SledError(#[from] sled_overlay::sled::Error),
351  
352      #[cfg(feature = "sled-overlay")]
353      #[error(transparent)]
354      SledTransactionError(#[from] sled_overlay::sled::transaction::TransactionError),
355  
356      #[error("Transaction {0} not found in database")]
357      TransactionNotFound(String),
358  
359      #[error("Transaction already seen")]
360      TransactionAlreadySeen,
361  
362      #[error("Input vectors have different length")]
363      InvalidInputLengths,
364  
365      #[error("Header {0} not found in database")]
366      HeaderNotFound(String),
367  
368      #[error("Block {0} is invalid")]
369      BlockIsInvalid(String),
370  
371      #[error("Block version {0} is invalid")]
372      BlockVersionIsInvalid(u8),
373  
374      #[error("Block {0} already in database")]
375      BlockAlreadyExists(String),
376  
377      #[error("Block {0} not found in database")]
378      BlockNotFound(String),
379  
380      #[error("Block with height number {0} not found in database")]
381      BlockHeightNotFound(u32),
382  
383      #[error("Block difficulty for height number {0} not found in database")]
384      BlockDifficultyNotFound(u32),
385  
386      #[error("Block state inverse diff for height number {0} not found in database")]
387      BlockStateInverseDiffNotFound(u32),
388  
389      #[error("Block {0} contains 0 transactions")]
390      BlockContainsNoTransactions(String),
391  
392      #[error("Contract {0} not found in database")]
393      ContractNotFound(String),
394  
395      #[error("Contract state tree not found")]
396      ContractStateNotFound,
397  
398      #[error("Contract already initialized")]
399      ContractAlreadyInitialized,
400  
401      #[error("zkas bincode not found in sled database")]
402      ZkasBincodeNotFound,
403  
404      // ===================
405      // wasm runtime errors
406      // ===================
407      #[cfg(feature = "wasm-runtime")]
408      #[error("Wasmer compile error: {0}")]
409      WasmerCompileError(String),
410  
411      #[cfg(feature = "wasm-runtime")]
412      #[error("Wasmer export error: {0}")]
413      WasmerExportError(String),
414  
415      #[cfg(feature = "wasm-runtime")]
416      #[error("Wasmer runtime error: {0}")]
417      WasmerRuntimeError(String),
418  
419      #[cfg(feature = "wasm-runtime")]
420      #[error("Wasmer instantiation error: {0}")]
421      WasmerInstantiationError(String),
422  
423      #[cfg(feature = "wasm-runtime")]
424      #[error("wasm memory error")]
425      WasmerMemoryError(String),
426  
427      #[cfg(feature = "wasm-runtime")]
428      #[error("wasm runtime out of memory")]
429      WasmerOomError(String),
430  
431      #[cfg(feature = "darkfi-sdk")]
432      #[error("Contract execution failed: {0}")]
433      ContractError(darkfi_sdk::error::ContractError),
434  
435      #[cfg(feature = "darkfi-sdk")]
436      #[error("Invalid DarkTree: {0}")]
437      DarkTreeError(darkfi_sdk::error::DarkTreeError),
438  
439      #[cfg(feature = "blockchain")]
440      #[error("contract wasm bincode not found")]
441      WasmBincodeNotFound,
442  
443      #[cfg(feature = "wasm-runtime")]
444      #[error("contract initialize error")]
445      ContractInitError(u64),
446  
447      #[cfg(feature = "wasm-runtime")]
448      #[error("contract execution error")]
449      ContractExecError(u64),
450  
451      #[cfg(feature = "wasm-runtime")]
452      #[error("wasm function ACL denied")]
453      WasmFunctionAclDenied,
454  
455      // ====================
456      // Event Graph errors
457      // ====================
458      #[error("Event is not found in tree: {0}")]
459      EventNotFound(String),
460  
461      #[error("Event is invalid")]
462      EventIsInvalid,
463  
464      // ====================
465      // Miscellaneous errors
466      // ====================
467      #[error("IO error: {0}")]
468      Io(std::io::ErrorKind),
469  
470      #[error("Infallible error: {0}")]
471      InfallibleError(String),
472  
473      #[cfg(feature = "smol")]
474      #[error("async_channel sender error: {0}")]
475      AsyncChannelSendError(String),
476  
477      #[cfg(feature = "smol")]
478      #[error("async_channel receiver error: {0}")]
479      AsyncChannelRecvError(String),
480  
481      #[cfg(feature = "util")]
482      #[error("tracing-subscriber init failed: {0}")]
483      LogInitError(String),
484  
485      #[error("ValueIsNotObject")]
486      ValueIsNotObject,
487  
488      #[error("No config file detected")]
489      ConfigNotFound,
490  
491      #[error("Invalid config file detected")]
492      ConfigInvalid,
493  
494      #[error("Configuration error: {0}")]
495      ConfigError(String),
496  
497      #[error("Failed decoding bincode: {0}")]
498      ZkasDecoderError(String),
499  
500      #[cfg(feature = "util")]
501      #[error("System clock is not correct!")]
502      InvalidClock,
503  
504      #[error("Unsupported OS")]
505      UnsupportedOS,
506  
507      #[error("System clock went backwards")]
508      BackwardsTime(std::time::SystemTimeError),
509  
510      #[error("Detached task stopped")]
511      DetachedTaskStopped,
512  
513      #[error("Addition overflow")]
514      AdditionOverflow,
515  
516      #[error("Subtraction underflow")]
517      SubtractionUnderflow,
518  
519      // ==============================================
520      // Wrappers for other error types in this library
521      // ==============================================
522      #[error(transparent)]
523      ClientFailed(#[from] ClientFailed),
524  
525      #[cfg(feature = "tx")]
526      #[error(transparent)]
527      TxVerifyFailed(#[from] TxVerifyFailed),
528  
529      //=============
530      // clock
531      //=============
532      #[error("clock out of sync with peers: {0}")]
533      ClockOutOfSync(String),
534  
535      // ================
536      // DHT/Geode errors
537      // ================
538      #[error("Geode needs garbage collection")]
539      GeodeNeedsGc,
540  
541      #[error("Geode file not found")]
542      GeodeFileNotFound,
543  
544      #[error("Geode chunk not found")]
545      GeodeChunkNotFound,
546  
547      #[error("Geode file route not found")]
548      GeodeFileRouteNotFound,
549  
550      #[error("Geode chunk route not found")]
551      GeodeChunkRouteNotFound,
552  
553      // ==================
554      // Event Graph errors
555      // ==================
556      #[error("DAG sync failed")]
557      DagSyncFailed,
558  
559      #[error("Malicious flood detected")]
560      MaliciousFlood,
561  
562      // =========
563      // Catch-all
564      // =========
565      #[error("{0}")]
566      Custom(String),
567  }
568  
569  #[cfg(feature = "tx")]
570  impl Error {
571      /// Auxiliary function to retrieve the vector of erroneous
572      /// transactions from a TxVerifyFailed error.
573      /// In any other case, we return the error itself.
574      pub fn retrieve_erroneous_txs(&self) -> Result<Vec<crate::tx::Transaction>> {
575          if let Self::TxVerifyFailed(TxVerifyFailed::ErroneousTxs(erroneous_txs)) = self {
576              return Ok(erroneous_txs.clone())
577          };
578  
579          Err(self.clone())
580      }
581  }
582  
583  #[cfg(feature = "tx")]
584  /// Transaction verification errors
585  #[derive(Debug, Clone, thiserror::Error)]
586  pub enum TxVerifyFailed {
587      #[error("Transaction {0} already exists")]
588      AlreadySeenTx(String),
589  
590      #[error("Invalid transaction signature")]
591      InvalidSignature,
592  
593      #[error("Missing signatures in transaction")]
594      MissingSignatures,
595  
596      #[error("Missing contract calls in transaction")]
597      MissingCalls,
598  
599      #[error("Invalid ZK proof in transaction")]
600      InvalidZkProof,
601  
602      #[error("Missing Money::Fee call in transaction")]
603      MissingFee,
604  
605      #[error("Invalid Money::Fee call in transaction")]
606      InvalidFee,
607  
608      #[error("Insufficient fee paid")]
609      InsufficientFee,
610  
611      #[error("Erroneous transactions found")]
612      ErroneousTxs(Vec<crate::tx::Transaction>),
613  }
614  
615  /// Client module errors
616  #[derive(Debug, Clone, thiserror::Error)]
617  pub enum ClientFailed {
618      #[error("IO error: {0}")]
619      Io(std::io::ErrorKind),
620  
621      #[error("Not enough value: {0}")]
622      NotEnoughValue(u64),
623  
624      #[error("Invalid address: {0}")]
625      InvalidAddress(String),
626  
627      #[error("Invalid amount: {0}")]
628      InvalidAmount(u64),
629  
630      #[error("Invalid token ID: {0}")]
631      InvalidTokenId(String),
632  
633      #[error("Internal error: {0}")]
634      InternalError(String),
635  
636      #[error("Verify error: {0}")]
637      VerifyError(String),
638  }
639  
640  #[cfg(feature = "rpc")]
641  #[derive(Clone, Debug, thiserror::Error)]
642  pub enum RpcError {
643      #[error("Connection closed: {0}")]
644      ConnectionClosed(String),
645  
646      #[error("Invalid JSON: {0}")]
647      InvalidJson(String),
648  
649      #[error("IO Error: {0}")]
650      IoError(std::io::ErrorKind),
651  
652      #[error("Method not found: {0}")]
653      MethodNotFound(String),
654  
655      #[error("Server-side Error: {0}")]
656      ServerError(#[from] std::sync::Arc<dyn std::error::Error + Send + Sync + 'static>),
657  }
658  
659  #[cfg(feature = "rpc")]
660  impl From<std::io::Error> for RpcError {
661      fn from(err: std::io::Error) -> Self {
662          Self::IoError(err.kind())
663      }
664  }
665  
666  #[cfg(feature = "rpc")]
667  impl From<RpcError> for Error {
668      fn from(err: RpcError) -> Self {
669          Self::RpcServerError(err)
670      }
671  }
672  
673  impl From<Error> for ClientFailed {
674      fn from(err: Error) -> Self {
675          Self::InternalError(err.to_string())
676      }
677  }
678  
679  impl From<std::io::Error> for ClientFailed {
680      fn from(err: std::io::Error) -> Self {
681          Self::Io(err.kind())
682      }
683  }
684  
685  impl From<std::io::Error> for Error {
686      fn from(err: std::io::Error) -> Self {
687          Self::Io(err.kind())
688      }
689  }
690  
691  impl From<std::time::SystemTimeError> for Error {
692      fn from(err: std::time::SystemTimeError) -> Self {
693          Self::BackwardsTime(err)
694      }
695  }
696  
697  impl From<std::convert::Infallible> for Error {
698      fn from(err: std::convert::Infallible) -> Self {
699          Self::InfallibleError(err.to_string())
700      }
701  }
702  
703  impl From<()> for Error {
704      fn from(_err: ()) -> Self {
705          Self::InfallibleError("Infallible".into())
706      }
707  }
708  
709  #[cfg(feature = "net")]
710  impl From<std::collections::TryReserveError> for Error {
711      fn from(err: std::collections::TryReserveError) -> Self {
712          Self::DecodePacket(err.to_string())
713      }
714  }
715  #[cfg(feature = "smol")]
716  impl<T> From<smol::channel::SendError<T>> for Error {
717      fn from(err: smol::channel::SendError<T>) -> Self {
718          Self::AsyncChannelSendError(err.to_string())
719      }
720  }
721  
722  #[cfg(feature = "smol")]
723  impl From<smol::channel::RecvError> for Error {
724      fn from(err: smol::channel::RecvError) -> Self {
725          Self::AsyncChannelRecvError(err.to_string())
726      }
727  }
728  
729  #[cfg(feature = "halo2_proofs")]
730  impl From<halo2_proofs::plonk::Error> for Error {
731      fn from(err: halo2_proofs::plonk::Error) -> Self {
732          Self::PlonkError(err.to_string())
733      }
734  }
735  
736  #[cfg(feature = "semver")]
737  impl From<semver::Error> for Error {
738      fn from(err: semver::Error) -> Self {
739          Self::SemverError(err.to_string())
740      }
741  }
742  
743  #[cfg(feature = "tinyjson")]
744  impl From<tinyjson::JsonParseError> for Error {
745      fn from(err: tinyjson::JsonParseError) -> Self {
746          Self::JsonParseError(err.to_string())
747      }
748  }
749  
750  #[cfg(feature = "tinyjson")]
751  impl From<tinyjson::JsonGenerateError> for Error {
752      fn from(err: tinyjson::JsonGenerateError) -> Self {
753          Self::JsonGenerateError(err.to_string())
754      }
755  }
756  
757  #[cfg(feature = "wasm-runtime")]
758  impl From<wasmer::CompileError> for Error {
759      fn from(err: wasmer::CompileError) -> Self {
760          Self::WasmerCompileError(err.to_string())
761      }
762  }
763  
764  #[cfg(feature = "wasm-runtime")]
765  impl From<wasmer::ExportError> for Error {
766      fn from(err: wasmer::ExportError) -> Self {
767          Self::WasmerExportError(err.to_string())
768      }
769  }
770  
771  #[cfg(feature = "wasm-runtime")]
772  impl From<wasmer::RuntimeError> for Error {
773      fn from(err: wasmer::RuntimeError) -> Self {
774          Self::WasmerRuntimeError(err.to_string())
775      }
776  }
777  
778  #[cfg(feature = "wasm-runtime")]
779  impl From<wasmer::InstantiationError> for Error {
780      fn from(err: wasmer::InstantiationError) -> Self {
781          Self::WasmerInstantiationError(err.to_string())
782      }
783  }
784  
785  #[cfg(feature = "wasm-runtime")]
786  impl From<wasmer::MemoryAccessError> for Error {
787      fn from(err: wasmer::MemoryAccessError) -> Self {
788          Self::WasmerMemoryError(err.to_string())
789      }
790  }
791  
792  #[cfg(feature = "wasm-runtime")]
793  impl From<wasmer::MemoryError> for Error {
794      fn from(err: wasmer::MemoryError) -> Self {
795          Self::WasmerOomError(err.to_string())
796      }
797  }
798  
799  #[cfg(feature = "darkfi-sdk")]
800  impl From<darkfi_sdk::error::ContractError> for Error {
801      fn from(err: darkfi_sdk::error::ContractError) -> Self {
802          Self::ContractError(err)
803      }
804  }
805  
806  #[cfg(feature = "darkfi-sdk")]
807  impl From<darkfi_sdk::error::DarkTreeError> for Error {
808      fn from(err: darkfi_sdk::error::DarkTreeError) -> Self {
809          Self::DarkTreeError(err)
810      }
811  }
812  
813  #[cfg(feature = "util")]
814  impl From<tracing_subscriber::util::TryInitError> for Error {
815      fn from(err: tracing_subscriber::util::TryInitError) -> Self {
816          Self::LogInitError(err.to_string())
817      }
818  }