parazyd 4 лет назад
Родитель
Сommit
a3829e76b3
12 измененных файлов с 328 добавлено и 356 удалено
  1. 2 2
      src/crypto/token_list.rs
  2. 281 230
      src/error.rs
  3. 18 18
      src/lib.rs
  4. 13 43
      src/node/client.rs
  5. 2 40
      src/node/state.rs
  6. 1 1
      src/rpc/rpcserver2.rs
  7. 3 5
      src/rpc/websockets.rs
  8. 1 1
      src/tx/mod.rs
  9. 1 1
      src/util/net_name.rs
  10. 3 3
      src/wallet/cashierdb.rs
  11. 0 9
      src/wallet/mod.rs
  12. 3 3
      src/wallet/walletdb.rs

+ 2 - 2
src/crypto/token_list.rs

@@ -105,7 +105,7 @@ impl DrkTokenList {
             return Ok((symbol.to_string(), generate_id2(token_id, network_name)?))
             return Ok((symbol.to_string(), generate_id2(token_id, network_name)?))
         };
         };
 
 
-        Err(Error::NotSupportedToken)
+        Err(Error::UnsupportedToken)
     }
     }
 
 
     pub fn symbol_from_id(&self, id: &DrkTokenId) -> Result<Option<(NetworkName, String)>> {
     pub fn symbol_from_id(&self, id: &DrkTokenId) -> Result<Option<(NetworkName, String)>> {
@@ -157,7 +157,7 @@ pub fn assign_id(
                 symbol_to_id(&tok_lower, eth_tokenlist)
                 symbol_to_id(&tok_lower, eth_tokenlist)
             }
             }
         }
         }
-        _ => Err(Error::NotSupportedNetwork),
+        _ => Err(Error::UnsupportedCoinNetwork),
     }
     }
 }
 }
 
 

+ 281 - 230
src/error.rs

@@ -1,149 +1,96 @@
-pub type Result<T> = std::result::Result<T, Error>;
+// Hello developer. Please add your error to the according subsection
+// that is commented, or make a new subsection. Keep it clean.
 
 
-#[derive(Clone, Debug, thiserror::Error)]
-pub enum Error {
-    #[error("io error: `{0:?}`")]
-    Io(std::io::ErrorKind),
+/// Main result type used throughout the codebase.
+pub type Result<T> = std::result::Result<T, Error>;
 
 
-    #[error("Infallible Error: `{0}`")]
-    InfallibleError(String),
+/// Result type used in transaction verifications
+pub type VerifyResult<T> = std::result::Result<T, VerifyFailed>;
 
 
-    #[cfg(feature = "util")]
-    #[error("VarInt was encoded in a non-minimal way")]
-    NonMinimalVarInt,
+/// Result type used in the Client module
+pub type ClientResult<T> = std::result::Result<T, ClientFailed>;
 
 
-    #[cfg(feature = "util")]
-    #[error("parse failed: `{0}`")]
+/// General library errors used throughout the codebase.
+#[derive(Debug, Clone, thiserror::Error)]
+pub enum Error {
+    // ==============
+    // Parsing errors
+    // ==============
+    #[error("Parse failed: {0}")]
     ParseFailed(&'static str),
     ParseFailed(&'static str),
 
 
-    #[error("decode failed: `{0}`")]
-    DecodeError(&'static str),
-
-    #[error("encode failed: `{0}`")]
-    EncodeError(&'static str),
-
     #[error(transparent)]
     #[error(transparent)]
     ParseIntError(#[from] std::num::ParseIntError),
     ParseIntError(#[from] std::num::ParseIntError),
 
 
     #[error(transparent)]
     #[error(transparent)]
     ParseFloatError(#[from] std::num::ParseFloatError),
     ParseFloatError(#[from] std::num::ParseFloatError),
 
 
-    #[cfg(feature = "util")]
+    #[cfg(feature = "num-bigint")]
     #[error(transparent)]
     #[error(transparent)]
     ParseBigIntError(#[from] num_bigint::ParseBigIntError),
     ParseBigIntError(#[from] num_bigint::ParseBigIntError),
 
 
-    #[cfg(any(feature = "rpc", feature = "node", feature = "util"))]
-    #[error("Url parse error `{0}`")]
-    UrlParseError(String),
-
-    #[cfg(any(feature = "rpc"))]
-    #[error("Socks error `{0}`")]
-    SocksError(String),
+    #[cfg(feature = "num-bigint")]
+    #[error(transparent)]
+    TryFromBigIntError(#[from] num_bigint::TryFromBigIntError<num_bigint::BigUint>),
 
 
-    #[error("No url found")]
-    NoUrlFound,
+    #[cfg(feature = "url")]
+    #[error(transparent)]
+    UrlParseError(#[from] url::ParseError),
 
 
-    #[error("No socks5 url found")]
-    NoSocks5UrlFound,
+    #[error("URL parse error: {0}")]
+    UrlParse(String),
 
 
     #[error(transparent)]
     #[error(transparent)]
     AddrParseError(#[from] std::net::AddrParseError),
     AddrParseError(#[from] std::net::AddrParseError),
 
 
+    #[error("Could not parse token parameter")]
+    TokenParseError,
+
+    // ===============
+    // Encoding errors
+    // ===============
+    #[error("decode failed: {0}")]
+    DecodeError(&'static str),
+
+    #[error("encode failed: {0}")]
+    EncodeError(&'static str),
+
+    #[error("VarInt was encoded in a non-minimal way")]
+    NonMinimalVarInt,
+
     #[error(transparent)]
     #[error(transparent)]
     Utf8Error(#[from] std::string::FromUtf8Error),
     Utf8Error(#[from] std::string::FromUtf8Error),
 
 
     #[error(transparent)]
     #[error(transparent)]
     StrUtf8Error(#[from] std::str::Utf8Error),
     StrUtf8Error(#[from] std::str::Utf8Error),
 
 
-    #[error("TryFrom error")]
-    TryFromError,
-
-    #[cfg(feature = "util")]
-    #[error(transparent)]
-    TryFromBigIntError(#[from] num_bigint::TryFromBigIntError<num_bigint::BigUint>),
-
-    #[cfg(feature = "util")]
-    #[error("Json serialization error: `{0}`")]
+    #[cfg(feature = "serde_json")]
+    #[error("serde_json error: {0}")]
     SerdeJsonError(String),
     SerdeJsonError(String),
 
 
-    #[cfg(feature = "util")]
+    #[cfg(feature = "toml")]
     #[error(transparent)]
     #[error(transparent)]
     TomlDeserializeError(#[from] toml::de::Error),
     TomlDeserializeError(#[from] toml::de::Error),
 
 
-    #[cfg(feature = "util")]
-    #[error("Bincode serialization error: `{0}`")]
+    #[cfg(feature = "bincode")]
+    #[error("bincode error: {0}")]
     BincodeError(String),
     BincodeError(String),
 
 
-    #[error("Bad operation type byte")]
-    BadOperationType,
-
-    #[error("Invalid param name")]
-    InvalidParamName,
-
-    #[error("Invalid param type")]
-    InvalidParamType,
-
-    #[error("Missing params")]
-    MissingParams,
-
-    #[cfg(feature = "crypto")]
-    #[error("Plonk error: `{0}`")]
-    PlonkError(String),
-
-    #[cfg(feature = "crypto")]
-    #[error("Unable to decrypt mint note")]
-    NoteDecryptionFailed,
-
-    #[cfg(feature = "node")]
+    #[cfg(feature = "bs58")]
     #[error(transparent)]
     #[error(transparent)]
-    VerifyFailed(#[from] crate::node::state::VerifyFailed),
-
-    #[error("Services Error: `{0}`")]
-    ServicesError(&'static str),
-
-    #[error("Client failed: `{0}`")]
-    ClientFailed(String),
-
-    #[error("Wallet error: `{0}`")]
-    WalletError(String),
-
-    #[error("Cashier failed: `{0}`")]
-    CashierError(String),
-
-    #[error("ZmqError: `{0}`")]
-    ZmqError(String),
-
-    #[cfg(feature = "blockchain")]
-    #[error("Rocksdb error: `{0}`")]
-    RocksdbError(String),
+    Bs58DecodeError(#[from] bs58::decode::Error),
 
 
-    #[cfg(feature = "wallet")]
-    #[error("sqlx error: `{0}`")]
-    SqlxError(String),
-
-    #[cfg(feature = "node")]
-    #[error("SlabsStore Error: `{0}`")]
-    SlabsStore(String),
-
-    #[error("JsonRpc Error: `{0}`")]
-    JsonRpcError(String),
-
-    #[error("Not supported network")]
-    NotSupportedNetwork,
-
-    #[error("Not supported token")]
-    NotSupportedToken,
+    #[error("Bad operation type byte")]
+    BadOperationType,
 
 
-    #[error("Could not parse token parameter")]
-    TokenParseError,
+    // ======================
+    // Network-related errors
+    // ======================
+    #[error("Unsupported network transport: {0}")]
+    UnsupportedTransport(String),
 
 
-    #[cfg(feature = "async-net")]
-    #[error("Async_Native_TLS error: `{0}`")]
-    AsyncNativeTlsError(String),
-
-    #[cfg(feature = "websockets")]
-    #[error("TungsteniteError: `{0}`")]
-    TungsteniteError(String),
+    #[error("Transport error: {0}")]
+    TransportError(String),
 
 
     #[error("Connection failed")]
     #[error("Connection failed")]
     ConnectFailed,
     ConnectFailed,
@@ -166,230 +113,334 @@ pub enum Error {
     #[error("Malformed packet")]
     #[error("Malformed packet")]
     MalformedPacket,
     MalformedPacket,
 
 
-    #[error("No config file detected. Please create one.")]
-    ConfigNotFound,
+    #[error("Socks proxy error: {0}")]
+    SocksError(String),
 
 
-    #[cfg(feature = "util")]
-    #[error("No keypair file detected.")]
-    KeypairPathNotFound,
+    #[error("No Socks5 URL found")]
+    NoSocks5UrlFound,
 
 
-    #[error("No cashier public keys detected.")]
-    CashierKeysNotFound,
+    #[error("No URL found")]
+    NoUrlFound,
 
 
-    #[error("SetLoggerError")]
-    SetLoggerError,
+    #[cfg(feature = "tungstenite")]
+    #[error("tungstenite error: {0}")]
+    TungsteniteError(String),
 
 
-    #[error("ValueIsNotObject")]
-    ValueIsNotObject,
+    #[cfg(feature = "async-native-tls")]
+    #[error("async_native_tls error: {0}")]
+    AsyncNativeTlsError(String),
 
 
-    #[cfg(feature = "async-runtime")]
-    #[error("Async_channel sender error")]
-    AsyncChannelSenderError,
+    // =============
+    // Crypto errors
+    // =============
+    #[cfg(feature = "halo2_proofs")]
+    #[error("halo2 plonk error: {0}")]
+    PlonkError(String),
 
 
-    #[cfg(feature = "async-runtime")]
-    #[error(transparent)]
-    AsyncChannelReceiverError(#[from] async_channel::RecvError),
+    #[error("Unable to decrypt mint note")]
+    NoteDecryptionFailed,
+
+    #[error("No keypair file detected")]
+    KeypairPathNotFound,
 
 
-    #[cfg(feature = "crypto")]
-    #[error("Error converting bytes to PublicKey")]
+    #[error("Failed converting bytes to PublicKey")]
     PublicKeyFromBytes,
     PublicKeyFromBytes,
 
 
-    #[cfg(feature = "crypto")]
-    #[error("Error converting bytes to SecretKey")]
+    #[error("Failed converting bytes to SecretKey")]
     SecretKeyFromBytes,
     SecretKeyFromBytes,
 
 
-    #[cfg(feature = "crypto")]
-    #[error("Invalid Address")]
+    #[error("Failed converting b58 string to PublicKey")]
+    PublicKeyFromStr,
+
+    #[error("Failed converting bs58 string to SecretKey")]
+    SecretKeyFromStr,
+
+    #[error("Invalid DarkFi address")]
     InvalidAddress,
     InvalidAddress,
 
 
-    #[error("Invalid bincode: {0}")]
-    ZkasDecoderError(&'static str),
+    // =======================
+    // Protocol-related errors
+    // =======================
+    #[error("Unsupported chain")]
+    UnsupportedChain,
+
+    #[error("Unsupported token")]
+    UnsupportedToken,
+
+    #[error("Unsupported coin network")]
+    UnsupportedCoinNetwork,
+
+    #[error("Raft error: {0}")]
+    RaftError(String),
+
+    // ===============
+    // Database errors
+    // ===============
+    #[cfg(feature = "sqlx")]
+    #[error("Sqlx error: {0}")]
+    SqlxError(String),
 
 
+    #[cfg(feature = "sled")]
+    #[error(transparent)]
+    SledError(#[from] sled::Error),
+
+    // =============
+    // Wallet errors
+    // =============
+    #[error("Wallet password is empty")]
+    WalletEmptyPassword,
+
+    #[error("Merkle tree already exists in wallet")]
+    WalletTreeExists,
+
+    // ===================
+    // wasm runtime errors
+    // ===================
     #[cfg(feature = "wasm-runtime")]
     #[cfg(feature = "wasm-runtime")]
-    #[error("wasm export error: {0}")]
+    #[error("Wasmer compile error: {0}")]
+    WasmerCompileError(String),
+
+    #[cfg(feature = "wasm-runtime")]
+    #[error("Wasmer export error: {0}")]
     WasmerExportError(String),
     WasmerExportError(String),
 
 
     #[cfg(feature = "wasm-runtime")]
     #[cfg(feature = "wasm-runtime")]
-    #[error("wasm runtime error: {0}")]
+    #[error("Wasmer runtime error: {0}")]
     WasmerRuntimeError(String),
     WasmerRuntimeError(String),
 
 
     #[cfg(feature = "wasm-runtime")]
     #[cfg(feature = "wasm-runtime")]
-    #[error("wasm instantiation error: {0}")]
+    #[error("Wasmer instantiation error: {0}")]
     WasmerInstantiationError(String),
     WasmerInstantiationError(String),
 
 
-    #[cfg(feature = "wasm-runtime")]
-    #[error("wasm compile error: {0}")]
-    WasmerCompileError(String),
-
     #[cfg(feature = "wasm-runtime")]
     #[cfg(feature = "wasm-runtime")]
     #[error("wasm runtime out of memory")]
     #[error("wasm runtime out of memory")]
     WasmerOomError,
     WasmerOomError,
 
 
-    #[cfg(any(feature = "blockchain2", feature = "raft"))]
+    // ====================
+    // Miscellaneous errors
+    // ====================
+    #[error("IO error: {0}")]
+    Io(std::io::ErrorKind),
+
+    #[error("Infallible error: {0}")]
+    InfallibleError(String),
+
+    #[cfg(feature = "async-channel")]
+    #[error("async_channel sender error: {0}")]
+    AsyncChannelSendError(String),
+
+    #[cfg(feature = "async-channel")]
+    #[error("async_channel receiver error: {0}")]
+    AsyncChannelRecvError(String),
+
+    #[error("SetLogger (log crate) failed: {0}")]
+    SetLoggerError(String),
+
+    #[error("ValueIsNotObject")]
+    ValueIsNotObject,
+
+    #[error("No config file detected")]
+    ConfigNotFound,
+
+    #[error("Failed decoding bincode: {0}")]
+    ZkasDecoderError(&'static str),
+
+    // ==============================================
+    // Wrappers for other error types in this library
+    // ==============================================
     #[error(transparent)]
     #[error(transparent)]
-    SledError(#[from] sled::Error),
+    VerifyFailed(#[from] VerifyFailed),
 
 
-    #[cfg(feature = "raft")]
-    #[error("Raft Error: {0}")]
-    RaftError(String),
+    #[error(transparent)]
+    ClientFailed(#[from] ClientFailed),
+}
 
 
-    #[error("Unsupported network transport")]
-    UnsupportedTransport,
+/// Transaction verification errors
+#[derive(Debug, Clone, thiserror::Error)]
+pub enum VerifyFailed {
+    #[error("Invalid cashier/faucet public key for clear input {0}")]
+    InvalidCashierOrFaucetKey(usize),
 
 
-    #[cfg(feature = "net2")]
-    #[error("TransportError: {0}")]
-    TransportError(String),
+    #[error("Invalid Merkle root for input {0}")]
+    InvalidMerkle(usize),
 
 
-    #[error("Unsupported chain")]
-    UnsupportedChain,
+    #[error("Invalid signature for input {0}")]
+    InputSignature(usize),
+
+    #[error("Invalid signature for clear input {0}")]
+    ClearInputSignature(usize),
+
+    #[error("Token commitments in inputs or outputs to not match")]
+    TokenMismatch,
+
+    #[error("Money in does not match money out (value commitments)")]
+    MissingFunds,
+
+    #[error("Mint proof verification failure for input {0}")]
+    MintProof(usize),
+
+    #[error("Burn proof verification failure for input {0}")]
+    BurnProof(usize),
+
+    #[error("Internal error: {0}")]
+    InternalError(String),
 }
 }
 
 
-#[cfg(feature = "node")]
-impl From<zeromq::ZmqError> for Error {
-    fn from(err: zeromq::ZmqError) -> Error {
-        Error::ZmqError(err.to_string())
-    }
+/// Client module errors
+#[derive(Debug, Clone, thiserror::Error)]
+pub enum ClientFailed {
+    #[error("Not enough value: {0}")]
+    NotEnoughValue(u64),
+
+    #[error("Invalid address: {0}")]
+    InvalidAddress(String),
+
+    #[error("Invalid amount: {0}")]
+    InvalidAmount(u64),
+
+    #[error("Internal error: {0}")]
+    InternalError(String),
+
+    #[error("Verify error: {0}")]
+    VerifyError(String),
 }
 }
 
 
-#[cfg(feature = "blockchain")]
-impl From<rocksdb::Error> for Error {
-    fn from(err: rocksdb::Error) -> Error {
-        Error::RocksdbError(err.to_string())
+impl From<Error> for VerifyFailed {
+    fn from(err: Error) -> Self {
+        Self::InternalError(err.to_string())
     }
     }
 }
 }
 
 
-#[cfg(feature = "wallet")]
-impl From<sqlx::error::Error> for Error {
-    fn from(err: sqlx::error::Error) -> Error {
-        Error::SqlxError(err.to_string())
+impl From<Error> for ClientFailed {
+    fn from(err: Error) -> Self {
+        Self::InternalError(err.to_string())
     }
     }
 }
 }
 
 
-#[cfg(feature = "util")]
-impl From<serde_json::Error> for Error {
-    fn from(err: serde_json::Error) -> Error {
-        Error::SerdeJsonError(err.to_string())
+impl From<VerifyFailed> for ClientFailed {
+    fn from(err: VerifyFailed) -> Self {
+        Self::VerifyError(err.to_string())
     }
     }
 }
 }
 
 
 impl From<std::io::Error> for Error {
 impl From<std::io::Error> for Error {
-    fn from(err: std::io::Error) -> Error {
-        Error::Io(err.kind())
+    fn from(err: std::io::Error) -> Self {
+        Self::Io(err.kind())
     }
     }
 }
 }
 
 
-#[cfg(feature = "async-runtime")]
-impl<T> From<async_channel::SendError<T>> for Error {
-    fn from(_err: async_channel::SendError<T>) -> Error {
-        Error::AsyncChannelSenderError
+impl From<std::convert::Infallible> for Error {
+    fn from(err: std::convert::Infallible) -> Self {
+        Self::InfallibleError(err.to_string())
     }
     }
 }
 }
 
 
-#[cfg(feature = "async-net")]
-impl From<async_native_tls::Error> for Error {
-    fn from(err: async_native_tls::Error) -> Error {
-        Error::AsyncNativeTlsError(err.to_string())
+impl From<()> for Error {
+    fn from(_err: ()) -> Self {
+        Self::InfallibleError("Infallible".into())
     }
     }
 }
 }
 
 
-#[cfg(any(feature = "rpc", feature = "util"))]
-impl From<url::ParseError> for Error {
-    fn from(err: url::ParseError) -> Error {
-        Error::UrlParseError(err.to_string())
+#[cfg(feature = "async-channel")]
+impl<T> From<async_channel::SendError<T>> for Error {
+    fn from(err: async_channel::SendError<T>) -> Self {
+        Self::AsyncChannelSendError(err.to_string())
     }
     }
 }
 }
 
 
-#[cfg(feature = "node")]
-impl From<crate::node::client::ClientFailed> for Error {
-    fn from(err: crate::node::client::ClientFailed) -> Error {
-        Error::ClientFailed(err.to_string())
+#[cfg(feature = "async-channel")]
+impl From<async_channel::RecvError> for Error {
+    fn from(err: async_channel::RecvError) -> Self {
+        Self::AsyncChannelRecvError(err.to_string())
     }
     }
 }
 }
 
 
-#[cfg(feature = "wallet")]
-impl From<crate::wallet::WalletError> for Error {
-    fn from(err: crate::wallet::WalletError) -> Error {
-        Error::WalletError(err.to_string())
+#[cfg(feature = "async-native-tls")]
+impl From<async_native_tls::Error> for Error {
+    fn from(err: async_native_tls::Error) -> Self {
+        Self::AsyncNativeTlsError(err.to_string())
     }
     }
 }
 }
 
 
 impl From<log::SetLoggerError> for Error {
 impl From<log::SetLoggerError> for Error {
-    fn from(_err: log::SetLoggerError) -> Error {
-        Error::SetLoggerError
+    fn from(err: log::SetLoggerError) -> Self {
+        Self::SetLoggerError(err.to_string())
     }
     }
 }
 }
 
 
-#[cfg(feature = "websockets")]
-impl From<tungstenite::Error> for Error {
-    fn from(err: tungstenite::Error) -> Error {
-        Error::TungsteniteError(err.to_string())
+#[cfg(feature = "sqlx")]
+impl From<sqlx::error::Error> for Error {
+    fn from(err: sqlx::error::Error) -> Self {
+        Self::SqlxError(err.to_string())
     }
     }
 }
 }
 
 
-#[cfg(feature = "util")]
-impl From<Box<bincode::ErrorKind>> for Error {
-    fn from(err: Box<bincode::ErrorKind>) -> Error {
-        Error::BincodeError(err.to_string())
+#[cfg(feature = "halo2_proofs")]
+impl From<halo2_proofs::plonk::Error> for Error {
+    fn from(err: halo2_proofs::plonk::Error) -> Self {
+        Self::PlonkError(err.to_string())
     }
     }
 }
 }
 
 
-#[cfg(feature = "rpc")]
-impl From<fast_socks5::SocksError> for Error {
-    fn from(err: fast_socks5::SocksError) -> Error {
-        Error::SocksError(err.to_string())
+#[cfg(feature = "tungstenite")]
+impl From<tungstenite::Error> for Error {
+    fn from(err: tungstenite::Error) -> Self {
+        Self::TungsteniteError(err.to_string())
     }
     }
 }
 }
 
 
-impl From<std::convert::Infallible> for Error {
-    fn from(err: std::convert::Infallible) -> Error {
-        Error::InfallibleError(err.to_string())
+#[cfg(feature = "bincode")]
+impl From<bincode::ErrorKind> for Error {
+    fn from(err: bincode::ErrorKind) -> Self {
+        Self::BincodeError(err.to_string())
     }
     }
 }
 }
 
 
-impl From<()> for Error {
-    fn from(_err: ()) -> Error {
-        Error::InfallibleError("Infallible".into())
+#[cfg(feature = "bincode")]
+impl From<Box<bincode::ErrorKind>> for Error {
+    fn from(err: Box<bincode::ErrorKind>) -> Self {
+        Self::BincodeError(err.to_string())
     }
     }
 }
 }
 
 
-#[cfg(feature = "crypto")]
-impl From<halo2_proofs::plonk::Error> for Error {
-    fn from(err: halo2_proofs::plonk::Error) -> Error {
-        Error::PlonkError(err.to_string())
+#[cfg(feature = "serde_json")]
+impl From<serde_json::Error> for Error {
+    fn from(err: serde_json::Error) -> Self {
+        Self::SerdeJsonError(err.to_string())
     }
     }
 }
 }
 
 
-#[cfg(feature = "wasm-runtime")]
-impl From<wasmer::CompileError> for Error {
-    fn from(err: wasmer::CompileError) -> Error {
-        Error::WasmerCompileError(err.to_string())
+#[cfg(feature = "fast-socks5")]
+impl From<fast_socks5::SocksError> for Error {
+    fn from(err: fast_socks5::SocksError) -> Self {
+        Self::SocksError(err.to_string())
     }
     }
 }
 }
 
 
 #[cfg(feature = "wasm-runtime")]
 #[cfg(feature = "wasm-runtime")]
-impl From<wasmer::ExportError> for Error {
-    fn from(err: wasmer::ExportError) -> Error {
-        Error::WasmerExportError(err.to_string())
+impl From<wasmer::CompileError> for Error {
+    fn from(err: wasmer::CompileError) -> Self {
+        Self::WasmerCompileError(err.to_string())
     }
     }
 }
 }
 
 
-#[cfg(feature = "net2")]
-impl<T: std::fmt::Display> From<crate::net2::transport::TransportError<T>> for Error {
-    fn from(err: crate::net2::transport::TransportError<T>) -> Error {
-        Error::TransportError(err.to_string())
+#[cfg(feature = "wasm-runtime")]
+impl From<wasmer::ExportError> for Error {
+    fn from(err: wasmer::ExportError) -> Self {
+        Self::WasmerExportError(err.to_string())
     }
     }
 }
 }
 
 
 #[cfg(feature = "wasm-runtime")]
 #[cfg(feature = "wasm-runtime")]
 impl From<wasmer::RuntimeError> for Error {
 impl From<wasmer::RuntimeError> for Error {
-    fn from(err: wasmer::RuntimeError) -> Error {
-        Error::WasmerRuntimeError(err.to_string())
+    fn from(err: wasmer::RuntimeError) -> Self {
+        Self::WasmerRuntimeError(err.to_string())
     }
     }
 }
 }
 
 
 #[cfg(feature = "wasm-runtime")]
 #[cfg(feature = "wasm-runtime")]
 impl From<wasmer::InstantiationError> for Error {
 impl From<wasmer::InstantiationError> for Error {
-    fn from(err: wasmer::InstantiationError) -> Error {
-        Error::WasmerInstantiationError(err.to_string())
+    fn from(err: wasmer::InstantiationError) -> Self {
+        Self::WasmerInstantiationError(err.to_string())
     }
     }
 }
 }

+ 18 - 18
src/lib.rs

@@ -1,5 +1,5 @@
 pub mod error;
 pub mod error;
-pub use error::{Error, Result};
+pub use error::{ClientFailed, ClientResult, Error, Result, VerifyFailed, VerifyResult};
 
 
 #[cfg(feature = "blockchain")]
 #[cfg(feature = "blockchain")]
 pub mod blockchain;
 pub mod blockchain;
@@ -13,41 +13,41 @@ pub mod consensus;
 #[cfg(feature = "blockchain2")]
 #[cfg(feature = "blockchain2")]
 pub mod consensus2;
 pub mod consensus2;
 
 
-#[cfg(feature = "wasm-runtime")]
-pub mod runtime;
-
 #[cfg(feature = "crypto")]
 #[cfg(feature = "crypto")]
 pub mod crypto;
 pub mod crypto;
 
 
 #[cfg(feature = "crypto")]
 #[cfg(feature = "crypto")]
 pub mod zk;
 pub mod zk;
 
 
-#[cfg(feature = "node")]
-pub mod node;
-
-#[cfg(feature = "node")]
-pub mod tx;
-
 #[cfg(feature = "net")]
 #[cfg(feature = "net")]
 pub mod net;
 pub mod net;
 
 
 #[cfg(feature = "net2")]
 #[cfg(feature = "net2")]
 pub mod net2;
 pub mod net2;
 
 
-#[cfg(feature = "system")]
-pub mod system;
+#[cfg(feature = "node")]
+pub mod node;
 
 
-#[cfg(feature = "util")]
-pub mod util;
+#[cfg(feature = "wasm-runtime")]
+pub mod runtime;
+
+#[cfg(feature = "raft")]
+pub mod raft;
 
 
 #[cfg(feature = "rpc")]
 #[cfg(feature = "rpc")]
 pub mod rpc;
 pub mod rpc;
 
 
-#[cfg(feature = "zkas")]
-pub mod zkas;
+#[cfg(feature = "system")]
+pub mod system;
 
 
-#[cfg(feature = "raft")]
-pub mod raft;
+#[cfg(feature = "tx")]
+pub mod tx;
+
+#[cfg(feature = "util")]
+pub mod util;
 
 
 #[cfg(feature = "wallet")]
 #[cfg(feature = "wallet")]
 pub mod wallet;
 pub mod wallet;
+
+#[cfg(feature = "zkas")]
+pub mod zkas;

+ 13 - 43
src/node/client.rs

@@ -24,45 +24,13 @@ use crate::{
     util::serial::Encodable,
     util::serial::Encodable,
     wallet::walletdb::{Balances, WalletPtr},
     wallet::walletdb::{Balances, WalletPtr},
     zk::circuit::MintContract,
     zk::circuit::MintContract,
-    Result,
+    ClientFailed, ClientResult, Result,
 };
 };
 
 
-pub type ClientResult<T> = std::result::Result<T, ClientFailed>;
-
-#[derive(Debug, Clone, thiserror::Error)]
-pub enum ClientFailed {
-    #[error("Not enough value: {0}")]
-    NotEnoughValue(u64),
-
-    #[error("Invalid address: {0}")]
-    InvalidAddress(String),
-
-    #[error("Invalid amount: {0}")]
-    InvalidAmount(u64),
-
-    #[error("Client error: {0}")]
-    ClientError(String),
-
-    #[error("Verify error: {0}")]
-    VerifyError(String),
-}
-
-impl From<crate::error::Error> for ClientFailed {
-    fn from(err: crate::error::Error) -> Self {
-        Self::ClientError(err.to_string())
-    }
-}
-
-impl From<super::state::VerifyFailed> for ClientFailed {
-    fn from(err: super::state::VerifyFailed) -> Self {
-        Self::VerifyError(err.to_string())
-    }
-}
-
 /// The Client structure, used for transaction operations.
 /// The Client structure, used for transaction operations.
 /// This includes, receiving, broadcasting, and building.
 /// This includes, receiving, broadcasting, and building.
 pub struct Client {
 pub struct Client {
-    pub main_keypair: Keypair,
+    pub main_keypair: Mutex<Keypair>,
     wallet: WalletPtr,
     wallet: WalletPtr,
     mint_pk: Lazy<ProvingKey>,
     mint_pk: Lazy<ProvingKey>,
     burn_pk: Lazy<ProvingKey>,
     burn_pk: Lazy<ProvingKey>,
@@ -94,8 +62,7 @@ impl Client {
         info!(target: "client", "Main keypair: {}", Address::from(main_keypair.public));
         info!(target: "client", "Main keypair: {}", Address::from(main_keypair.public));
 
 
         Ok(Self {
         Ok(Self {
-            //main_keypair: Mutex::new(main_keypair),
-            main_keypair,
+            main_keypair: Mutex::new(main_keypair),
             wallet,
             wallet,
             mint_pk: Lazy::new(),
             mint_pk: Lazy::new(),
             burn_pk: Lazy::new(),
             burn_pk: Lazy::new(),
@@ -118,7 +85,7 @@ impl Client {
 
 
         if clear_input {
         if clear_input {
             debug!("build_slab_from_tx(): Building clear input");
             debug!("build_slab_from_tx(): Building clear input");
-            let signature_secret = self.main_keypair.secret;
+            let signature_secret = self.main_keypair.lock().await.secret;
             let input = TransactionBuilderClearInputInfo { value, token_id, signature_secret };
             let input = TransactionBuilderClearInputInfo { value, token_id, signature_secret };
             clear_inputs.push(input);
             clear_inputs.push(input);
         } else {
         } else {
@@ -160,7 +127,7 @@ impl Client {
                 outputs.push(TransactionBuilderOutputInfo {
                 outputs.push(TransactionBuilderOutputInfo {
                     value: return_value,
                     value: return_value,
                     token_id,
                     token_id,
-                    public: self.main_keypair.public,
+                    public: self.main_keypair.lock().await.public,
                 });
                 });
             }
             }
 
 
@@ -280,15 +247,18 @@ impl Client {
         self.wallet.put_keypair(keypair).await
         self.wallet.put_keypair(keypair).await
     }
     }
 
 
-    pub async fn set_default_keypair(&mut self, public: &PublicKey) -> Result<()> {
+    pub async fn set_default_keypair(&self, public: &PublicKey) -> Result<()> {
         self.wallet.set_default_keypair(public).await?;
         self.wallet.set_default_keypair(public).await?;
-        self.main_keypair = self.wallet.get_default_keypair().await?;
+        let kp = self.wallet.get_default_keypair().await?;
+        let mut mk = self.main_keypair.lock().await;
+        *mk = kp;
+        drop(mk);
         Ok(())
         Ok(())
     }
     }
 
 
-    pub async fn keygen(&self) -> Result<()> {
-        let _ = self.wallet.keygen().await?;
-        Ok(())
+    pub async fn keygen(&self) -> Result<Address> {
+        let kp = self.wallet.keygen().await?;
+        Ok(Address::from(kp.public))
     }
     }
 
 
     pub async fn get_balances(&self) -> Result<Balances> {
     pub async fn get_balances(&self) -> Result<Balances> {

+ 2 - 40
src/node/state.rs

@@ -16,47 +16,9 @@ use crate::{
     tx::Transaction,
     tx::Transaction,
     wallet::walletdb::WalletPtr,
     wallet::walletdb::WalletPtr,
     zk::circuit::{BurnContract, MintContract},
     zk::circuit::{BurnContract, MintContract},
-    Result,
+    Result, VerifyFailed, VerifyResult,
 };
 };
 
 
-pub type VerifyResult<T> = std::result::Result<T, VerifyFailed>;
-
-#[derive(Debug, Clone, thiserror::Error)]
-pub enum VerifyFailed {
-    #[error("Invalid cashier/faucet public key for clear input {0}")]
-    InvalidCashierOrFaucetKey(usize),
-
-    #[error("Invalid merkle root for input {0}")]
-    InvalidMerkle(usize),
-
-    #[error("Invalid signature for input {0}")]
-    InputSignature(usize),
-
-    #[error("Invalid signature for clear input {0}")]
-    ClearInputSignature(usize),
-
-    #[error("Token commitments in inputs or outputs do not match")]
-    AssetMismatch,
-
-    #[error("Money in does not match money out (value commitments")]
-    MissingFunds,
-
-    #[error("Mint proof verification failure for input {0}")]
-    MintProof(usize),
-
-    #[error("Burn proof verification failure for input {0}")]
-    BurnProof(usize),
-
-    #[error("Internal error: {0}")]
-    InternalError(String),
-}
-
-impl From<crate::error::Error> for VerifyFailed {
-    fn from(err: crate::error::Error) -> Self {
-        Self::InternalError(err.to_string())
-    }
-}
-
 /// Trait implementing the state functions used by the state transition.
 /// Trait implementing the state functions used by the state transition.
 pub trait ProgramState {
 pub trait ProgramState {
     /// Check if the public key is coming from a trusted cashier
     /// Check if the public key is coming from a trusted cashier
@@ -91,7 +53,7 @@ pub fn state_transition<S: ProgramState>(state: &S, tx: Transaction) -> VerifyRe
     debug!(target: "state_transition", "Iterate clear_inputs");
     debug!(target: "state_transition", "Iterate clear_inputs");
     for (i, input) in tx.clear_inputs.iter().enumerate() {
     for (i, input) in tx.clear_inputs.iter().enumerate() {
         let pk = &input.signature_public;
         let pk = &input.signature_public;
-        if !state.is_valid_cashier_public_key(pk) || !state.is_valid_faucet_public_key(pk) {
+        if !state.is_valid_cashier_public_key(pk) && !state.is_valid_faucet_public_key(pk) {
             error!(target: "state_transition", "Invalid pubkey for clear input: {:?}", pk);
             error!(target: "state_transition", "Invalid pubkey for clear input: {:?}", pk);
             return Err(VerifyFailed::InvalidCashierOrFaucetKey(i))
             return Err(VerifyFailed::InvalidCashierOrFaucetKey(i))
         }
         }

+ 1 - 1
src/rpc/rpcserver2.rs

@@ -96,7 +96,7 @@ pub async fn listen_and_serve(url: Url, rh: Arc<impl RequestHandler + 'static>)
 
 
         x => {
         x => {
             error!(target: "JSON-RPC SERVER", "Transport protocol '{}' isn't implemented", x);
             error!(target: "JSON-RPC SERVER", "Transport protocol '{}' isn't implemented", x);
-            Err(Error::UnsupportedTransport)
+            Err(Error::UnsupportedTransport(x.to_string()))
         }
         }
     }
     }
 }
 }

+ 3 - 5
src/rpc/websockets.rs

@@ -66,11 +66,11 @@ pub async fn connect(addr: &str, tls: TlsConnector) -> DrkResult<(WsStream, Resp
     let url = Url::parse(addr)?;
     let url = Url::parse(addr)?;
     let host = url
     let host = url
         .host_str()
         .host_str()
-        .ok_or_else(|| Error::UrlParseError(format!("Missing host in {}", url)))?
+        .ok_or_else(|| Error::UrlParse(format!("Missing host in {}", url)))?
         .to_string();
         .to_string();
     let port = url
     let port = url
         .port_or_known_default()
         .port_or_known_default()
-        .ok_or_else(|| Error::UrlParseError(format!("Missing port in {}", url)))?;
+        .ok_or_else(|| Error::UrlParse(format!("Missing port in {}", url)))?;
 
 
     let socket_addr = {
     let socket_addr = {
         let host = host.clone();
         let host = host.clone();
@@ -92,8 +92,6 @@ pub async fn connect(addr: &str, tls: TlsConnector) -> DrkResult<(WsStream, Resp
             let (stream, resp) = async_tungstenite::client_async(addr, stream).await?;
             let (stream, resp) = async_tungstenite::client_async(addr, stream).await?;
             Ok((WsStream::Tls(stream), resp))
             Ok((WsStream::Tls(stream), resp))
         }
         }
-        scheme => {
-            Err(Error::UrlParseError(format!("Invalid url scheme `{}`, in `{}`", scheme, url)))
-        }
+        scheme => Err(Error::UrlParse(format!("Invalid url scheme `{}`, in `{}`", scheme, url))),
     }
     }
 }
 }

+ 1 - 1
src/tx/mod.rs

@@ -113,7 +113,7 @@ impl Transaction {
         // Verify that the token commitments match
         // Verify that the token commitments match
         if !self.verify_token_commitments() {
         if !self.verify_token_commitments() {
             error!("tx::verify(): Token ID mismatch");
             error!("tx::verify(): Token ID mismatch");
-            return Err(VerifyFailed::AssetMismatch)
+            return Err(VerifyFailed::TokenMismatch)
         }
         }
 
 
         // Verify the available signatures
         // Verify the available signatures

+ 1 - 1
src/util/net_name.rs

@@ -42,7 +42,7 @@ impl FromStr for NetworkName {
             "sol" | "solana" => Ok(NetworkName::Solana),
             "sol" | "solana" => Ok(NetworkName::Solana),
             "btc" | "bitcoin" => Ok(NetworkName::Bitcoin),
             "btc" | "bitcoin" => Ok(NetworkName::Bitcoin),
             "eth" | "ethereum" => Ok(NetworkName::Ethereum),
             "eth" | "ethereum" => Ok(NetworkName::Ethereum),
-            _ => Err(crate::Error::NotSupportedNetwork),
+            _ => Err(crate::Error::UnsupportedCoinNetwork),
         }
         }
     }
     }
 }
 }

+ 3 - 3
src/wallet/cashierdb.rs

@@ -10,7 +10,6 @@ use sqlx::{
 
 
 use super::wallet_api::WalletApi;
 use super::wallet_api::WalletApi;
 
 
-use super::WalletError;
 use crate::{
 use crate::{
     crypto::{
     crypto::{
         keypair::{Keypair, PublicKey, SecretKey},
         keypair::{Keypair, PublicKey, SecretKey},
@@ -18,6 +17,7 @@ use crate::{
         types::DrkTokenId,
         types::DrkTokenId,
     },
     },
     util::NetworkName,
     util::NetworkName,
+    Error::{WalletEmptyPassword, WalletTreeExists},
     Result,
     Result,
 };
 };
 
 
@@ -54,7 +54,7 @@ impl CashierDb {
         debug!("new() Constructor called");
         debug!("new() Constructor called");
         if password.trim().is_empty() {
         if password.trim().is_empty() {
             error!("Password is empty. You must set a password to use the wallet.");
             error!("Password is empty. You must set a password to use the wallet.");
-            return Err(WalletError::EmptyPassword.into())
+            return Err(WalletEmptyPassword)
         }
         }
 
 
         if path != "sqlite::memory:" {
         if path != "sqlite::memory:" {
@@ -104,7 +104,7 @@ impl CashierDb {
         match sqlx::query("SELECT * FROM tree").fetch_one(&mut conn).await {
         match sqlx::query("SELECT * FROM tree").fetch_one(&mut conn).await {
             Ok(_) => {
             Ok(_) => {
                 error!("Merkle tree already exists");
                 error!("Merkle tree already exists");
-                Err(WalletError::TreeExists.into())
+                Err(WalletTreeExists)
             }
             }
             Err(_) => {
             Err(_) => {
                 let tree = BridgeTree::<MerkleNode, 32>::new(100);
                 let tree = BridgeTree::<MerkleNode, 32>::new(100);

+ 0 - 9
src/wallet/mod.rs

@@ -1,12 +1,3 @@
 pub mod cashierdb;
 pub mod cashierdb;
 pub mod wallet_api;
 pub mod wallet_api;
 pub mod walletdb;
 pub mod walletdb;
-
-#[derive(Debug, Clone, thiserror::Error)]
-pub enum WalletError {
-    #[error("Empty password")]
-    EmptyPassword,
-
-    #[error("Merkle tree already exists")]
-    TreeExists,
-}

+ 3 - 3
src/wallet/walletdb.rs

@@ -9,7 +9,6 @@ use sqlx::{
     ConnectOptions, Row, SqlitePool,
     ConnectOptions, Row, SqlitePool,
 };
 };
 
 
-use super::WalletError;
 use crate::{
 use crate::{
     crypto::{
     crypto::{
         coin::Coin,
         coin::Coin,
@@ -21,6 +20,7 @@ use crate::{
         OwnCoin, OwnCoins,
         OwnCoin, OwnCoins,
     },
     },
     util::serial::serialize,
     util::serial::serialize,
+    Error::{WalletEmptyPassword, WalletTreeExists},
     Result,
     Result,
 };
 };
 
 
@@ -50,7 +50,7 @@ impl WalletDb {
     pub async fn new(path: &str, password: &str) -> Result<WalletPtr> {
     pub async fn new(path: &str, password: &str) -> Result<WalletPtr> {
         if password.trim().is_empty() {
         if password.trim().is_empty() {
             error!("Password is empty. You must set a password to use the wallet.");
             error!("Password is empty. You must set a password to use the wallet.");
-            return Err(WalletError::EmptyPassword.into())
+            return Err(WalletEmptyPassword)
         }
         }
 
 
         if path != "sqlite::memory:" {
         if path != "sqlite::memory:" {
@@ -176,7 +176,7 @@ impl WalletDb {
         match sqlx::query("SELECT * FROM tree").fetch_one(&mut conn).await {
         match sqlx::query("SELECT * FROM tree").fetch_one(&mut conn).await {
             Ok(_) => {
             Ok(_) => {
                 error!("Merkle tree already exists");
                 error!("Merkle tree already exists");
-                Err(WalletError::TreeExists.into())
+                Err(WalletTreeExists)
             }
             }
             Err(_) => {
             Err(_) => {
                 let tree = BridgeTree::<MerkleNode, 32>::new(100);
                 let tree = BridgeTree::<MerkleNode, 32>::new(100);