Просмотр исходного кода

token_list: clean up & use bitcoin tokens from the json file

ghassmo 4 лет назад
Родитель
Сommit
1ea13805e6
3 измененных файлов с 101 добавлено и 68 удалено
  1. 34 32
      src/bin/darkfid.rs
  2. 23 17
      src/util/parse.rs
  3. 44 19
      src/util/token_list.rs

+ 34 - 32
src/bin/darkfid.rs

@@ -53,9 +53,9 @@ impl RequestHandler for Darkfid {
 
         if self.update_balances().await.is_err() {
             return JsonResult::Err(jsonerr(
-                InternalError,
-                Some("Unable to update balances".into()),
-                req.id,
+                    InternalError,
+                    Some("Unable to update balances".into()),
+                    req.id,
             ));
         }
 
@@ -80,6 +80,7 @@ struct Darkfid {
     state: Arc<Mutex<State>>,
     sol_tokenlist: TokenList,
     eth_tokenlist: TokenList,
+    btc_tokenlist: TokenList,
     drk_tokenlist: DrkTokenList,
     cashiers: Vec<Cashier>,
 }
@@ -92,13 +93,15 @@ impl Darkfid {
     ) -> Result<Self> {
         let sol_tokenlist = TokenList::new(include_bytes!("../../token/solana_token_list.json"))?;
         let eth_tokenlist = TokenList::new(include_bytes!("../../token/erc20_token_list.json"))?;
-        let drk_tokenlist = DrkTokenList::new(&sol_tokenlist, &eth_tokenlist)?;
+        let btc_tokenlist = TokenList::new(include_bytes!("../../token/bitcoin_token_list.json"))?;
+        let drk_tokenlist = DrkTokenList::new(&sol_tokenlist, &eth_tokenlist, &btc_tokenlist)?;
 
         Ok(Self {
             client,
             state,
             sol_tokenlist,
             eth_tokenlist,
+            btc_tokenlist,
             drk_tokenlist,
             cashiers,
         })
@@ -243,23 +246,22 @@ impl Darkfid {
                 }
                 #[cfg(feature = "btc")]
                 NetworkName::Bitcoin => {
-                    //hardcoded genesis coinbase address
-                    let token_id = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa".to_string();
-                    Ok(json!(token_id))
+                    if let Some(tkn) = self.btc_tokenlist.search_id(symbol)? {
+                        Ok(json!(tkn))
+                    } else {
+                        Err(Error::NotSupportedToken)
+                    }
                 }
                 #[cfg(feature = "eth")]
                 NetworkName::Ethereum => {
-                    // hardcoded genesis coinbase address
-                    let token_id: String = if symbol.to_lowercase() == "eth" {
+                    if symbol.to_lowercase() == "eth" {
                         use drk::service::eth::ETH_NATIVE_TOKEN_ID;
-                        ETH_NATIVE_TOKEN_ID.to_string()
+                        Ok(json!(ETH_NATIVE_TOKEN_ID.to_string()))
                     } else if let Some(tkn) = self.eth_tokenlist.search_id(symbol)? {
-                        tkn
+                        Ok(json!(tkn))
                     } else {
-                        return Err(Error::NotSupportedToken);
-                    };
-
-                    Ok(json!(token_id))
+                        Err(Error::NotSupportedToken)
+                    }
                 }
                 _ => Err(Error::NotSupportedNetwork),
             }
@@ -327,7 +329,7 @@ impl Darkfid {
             }
         }
 
-        let token_id = match assign_id(&network, token, &self.sol_tokenlist, &self.eth_tokenlist) {
+        let token_id = match assign_id(&network, token, &self.sol_tokenlist, &self.eth_tokenlist, &self.btc_tokenlist) {
             Ok(t) => t,
             Err(e) => {
                 return JsonResult::Err(jsonerr(InternalError, Some(e.to_string()), id));
@@ -420,7 +422,7 @@ impl Darkfid {
             }
         };
 
-        let token_id = match assign_id(&network, token, &self.sol_tokenlist, &self.eth_tokenlist) {
+        let token_id = match assign_id(&network, token, &self.sol_tokenlist, &self.eth_tokenlist,&self.btc_tokenlist ) {
             Ok(t) => t,
             Err(e) => {
                 return JsonResult::Err(jsonerr(InternalError, Some(e.to_string()), id));
@@ -476,11 +478,11 @@ impl Darkfid {
                 }
                 Ok(_) => {
                     rep = JsonResult::Resp(jsonresp(
-                        json!(format!(
-                            "Sent request to withdraw {} amount of {}",
-                            amount, token_id
-                        )),
-                        id.clone(),
+                            json!(format!(
+                                    "Sent request to withdraw {} amount of {}",
+                                    amount, token_id
+                            )),
+                            id.clone(),
                     ))
                 }
             }
@@ -650,7 +652,7 @@ async fn start(
         mint_params,
         spend_params,
     )
-    .await?;
+        .await?;
 
     let client = Arc::new(Mutex::new(client));
 
@@ -687,7 +689,7 @@ async fn main() -> Result<()> {
         (@arg refresh: -r --refresh "Refresh the wallet and slabstore")
         (@arg cashier: --cashier +takes_value "Local cashier public key")
     )
-    .get_matches();
+        .get_matches();
 
     let config_path = if args.is_present("CONFIG") {
         expand_path(args.value_of("CONFIG").unwrap())?
@@ -743,14 +745,14 @@ async fn main() -> Result<()> {
         .each(0..nthreads, |_| {
             smol::future::block_on(ex.run(shutdown.recv()))
         })
-        // Run the main future on the current thread.
-        .finish(|| {
-            smol::future::block_on(async move {
-                start(ex2, local_cashier, &config).await?;
-                drop(signal);
-                Ok::<(), drk::Error>(())
-            })
-        });
+    // Run the main future on the current thread.
+    .finish(|| {
+        smol::future::block_on(async move {
+            start(ex2, local_cashier, &config).await?;
+            drop(signal);
+            Ok::<(), drk::Error>(())
+        })
+    });
 
     result
 }

+ 23 - 17
src/util/parse.rs

@@ -48,35 +48,41 @@ pub fn assign_id(
     token: &str,
     sol_tokenlist: &TokenList,
     eth_tokenlist: &TokenList,
+    btc_tokenlist: &TokenList,
 ) -> Result<String> {
     match network {
         #[cfg(feature = "sol")]
         NetworkName::Solana => {
             // (== 44) can represent a Solana base58 token mint address
-            let id = if token.len() == 44 {
-                token.to_string()
+            if token.len() == 44 {
+                Ok(token.to_string())
             } else {
                 let tok_lower = token.to_lowercase();
-                symbol_to_id(&tok_lower, sol_tokenlist)?
-            };
-            Ok(id)
+                symbol_to_id(&tok_lower, sol_tokenlist)
+            }
         }
         #[cfg(feature = "btc")]
         NetworkName::Bitcoin => {
-            // FIXME should load the id from the json file
-            let id = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa".to_string();
-            Ok(id)
+            if token.len() == 34 {
+                Ok(token.to_string())
+            } else {
+                let tok_lower = token.to_lowercase();
+                symbol_to_id(&tok_lower, btc_tokenlist)
+            }
         }
         #[cfg(feature = "eth")]
         NetworkName::Ethereum => {
             use crate::service::eth::ETH_NATIVE_TOKEN_ID;
-            let id = if token == "eth" || token == ETH_NATIVE_TOKEN_ID {
-                token.to_string()
+            // (== 42) can represent a erc20 token mint address
+            if token.len() == 42 {
+                Ok(token.to_string())
+            }
+            else if token == "eth" {
+                Ok(ETH_NATIVE_TOKEN_ID.to_string())
             } else {
                 let tok_lower = token.to_lowercase();
-                symbol_to_id(&tok_lower, eth_tokenlist)?
-            };
-            Ok(id)
+                symbol_to_id(&tok_lower, eth_tokenlist)
+            }
         }
         _ => Err(Error::NotSupportedNetwork),
     }
@@ -156,10 +162,10 @@ pub fn decode_base10(amount: &str, decimal_places: usize, strict: bool) -> Resul
 
     // Round and return
     /*
-    if round && number == u64::MAX {
-    return Err(Error::ParseFailed("u64 overflow"));
-    }
-    */
+       if round && number == u64::MAX {
+       return Err(Error::ParseFailed("u64 overflow"));
+       }
+       */
 
     Ok(number + round as u64)
 }

+ 44 - 19
src/util/token_list.rs

@@ -61,36 +61,38 @@ pub struct DrkTokenList {
 }
 
 impl DrkTokenList {
-    pub fn new(sol_list: &TokenList, eth_list: &TokenList) -> Result<Self> {
+    pub fn new(sol_list: &TokenList, eth_list: &TokenList, btc_list: &TokenList) -> Result<Self> {
         let sol_symbols = sol_list.get_symbols()?;
         let eth_symbols = eth_list.get_symbols()?;
+        let btc_symbols = btc_list.get_symbols()?;
 
         let sol_tokens: HashMap<String, jubjub::Fr> = sol_symbols
             .iter()
             .filter_map(|symbol| {
                 Self::generate_hash_pair(sol_list, &NetworkName::Solana, symbol).ok()
             })
-            .collect();
+        .collect();
 
         let eth_tokens: HashMap<String, jubjub::Fr> = eth_symbols
             .iter()
             .filter_map(|symbol| {
                 Self::generate_hash_pair(eth_list, &NetworkName::Ethereum, symbol).ok()
             })
-            .collect();
+        .collect();
 
-        // FIXME
-        let mut btc_tokens: HashMap<String, jubjub::Fr> = HashMap::new();
-        btc_tokens.insert(
-            "BTC".to_string(),
-            generate_id("1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa", &NetworkName::Bitcoin)?,
-        );
-
-        let mut tokens: HashMap<NetworkName, HashMap<String, jubjub::Fr>> = HashMap::new();
+        let btc_tokens: HashMap<String, jubjub::Fr> = btc_symbols
+            .iter()
+            .filter_map(|symbol| {
+                Self::generate_hash_pair(btc_list, &NetworkName::Bitcoin, symbol).ok()
+            })
+        .collect();
 
-        tokens.insert(NetworkName::Solana, sol_tokens);
-        tokens.insert(NetworkName::Ethereum, eth_tokens);
-        tokens.insert(NetworkName::Bitcoin, btc_tokens);
+        let tokens: HashMap<NetworkName, HashMap<String, jubjub::Fr>> =
+            HashMap::from([
+                (NetworkName::Solana, sol_tokens),
+                (NetworkName::Ethereum, eth_tokens),
+                (NetworkName::Bitcoin, btc_tokens)
+            ]);
 
         Ok(Self { tokens })
     }
@@ -141,15 +143,28 @@ mod tests {
 
     fn _get_eth_tokens() -> Result<TokenList> {
         let file_contents = include_bytes!("../../testdata/erc20tokenlisttest.json");
-        let sol_tokenlist: Value = serde_json::from_slice(file_contents)?;
+        let eth_tokenlist: Value = serde_json::from_slice(file_contents)?;
 
-        let tokens = sol_tokenlist["tokens"]
+        let tokens = eth_tokenlist["tokens"]
             .as_array()
             .ok_or(Error::TokenParseError)?
             .clone();
 
-        let sol_tokenlist = TokenList { tokens };
-        Ok(sol_tokenlist)
+        let eth_tokenlist = TokenList { tokens };
+        Ok(eth_tokenlist)
+    }
+
+    fn _get_btc_tokens() -> Result<TokenList> {
+        let file_contents = include_bytes!("../../token/bitcoin_token_list.json");
+        let btc_tokenlist: Value = serde_json::from_slice(file_contents)?;
+
+        let tokens = btc_tokenlist["tokens"]
+            .as_array()
+            .ok_or(Error::TokenParseError)?
+            .clone();
+
+        let btc_tokenlist = TokenList { tokens };
+        Ok(btc_tokenlist)
     }
 
     #[test]
@@ -181,8 +196,10 @@ mod tests {
         let sol_tokens2 = _get_sol_tokens()?;
         let eth_tokens = _get_eth_tokens()?;
         let eth_tokens2 = _get_eth_tokens()?;
+        let btc_tokens = _get_btc_tokens()?;
+        let btc_tokens2 = _get_btc_tokens()?;
 
-        let drk_token = DrkTokenList::new(&sol_tokens, &eth_tokens)?;
+        let drk_token = DrkTokenList::new(&sol_tokens, &eth_tokens, &btc_tokens)?;
 
         assert_eq!(drk_token.tokens[&NetworkName::Solana].len(), 5);
         assert_eq!(drk_token.tokens[&NetworkName::Ethereum].len(), 3);
@@ -196,6 +213,14 @@ mod tests {
             )?
         );
 
+        assert_eq!(
+            drk_token.tokens[&NetworkName::Bitcoin]["BTC"],
+            generate_id(
+                &btc_tokens2.search_id("BTC")?.unwrap(),
+                &NetworkName::Bitcoin
+            )?
+        );
+
         assert_eq!(
             drk_token.tokens[&NetworkName::Ethereum]["WBTC"],
             generate_id(