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

eth: implement send and send to main wallet functions & clean up

ghassmo 4 лет назад
Родитель
Сommit
518d807a75
2 измененных файлов с 83 добавлено и 20 удалено
  1. 9 4
      src/bin/eth.rs
  2. 74 16
      src/service/eth.rs

+ 9 - 4
src/bin/eth.rs

@@ -1,7 +1,7 @@
 use num_bigint::BigUint;
 
 use drk::{
-    service::eth::{erc20_transfer_data, generate_privkey, EthClient, EthTx},
+    service::eth::{erc20_transfer_data, EthClient, EthTx},
     util::{decode_base10, encode_base10},
     Result,
 };
@@ -10,15 +10,20 @@ use drk::{
 async fn main() -> Result<()> {
     simple_logger::init_with_level(log::Level::Debug)?;
 
-    let eth = EthClient::new("/home/parazyd/.ethereum/ropsten/geth.ipc".to_string());
+    let acc = "0x113b6648f34f4d0340d04ff171cbcf0b49d47827".to_string();
+    let key = "67cbb73cb293eea5fa2a7025d5479dbd50319010c03fd8821917ad0d9d53276c".to_string();
+
+    let eth = EthClient::new(
+        "/home/parazyd/.ethereum/ropsten/geth.ipc".to_string(),
+        String::from("foobar"),
+        (key, acc.clone()),
+    );
 
     //let key = generate_privkey();
     //let passphrase = "foobar".to_string();
     //let rep = eth.import_privkey(&key, &passphrase).await?;
     //println!("{:#?}", rep);
 
-    let acc = "0x113b6648f34f4d0340d04ff171cbcf0b49d47827".to_string();
-    let _key = "67cbb73cb293eea5fa2a7025d5479dbd50319010c03fd8821917ad0d9d53276c".to_string();
     let passphrase = "foobar".to_string();
 
     // Recipient address

+ 74 - 16
src/service/eth.rs

@@ -17,7 +17,7 @@ use crate::{
     rpc::jsonrpc,
     rpc::jsonrpc::JsonResult,
     serial::{deserialize, serialize},
-    util::{generate_id, NetworkName},
+    util::{generate_id, parse::truncate, NetworkName},
     Error, Result,
 };
 
@@ -173,6 +173,9 @@ impl EthTx {
 // INFO [10-25|19:47:32.845] IPC endpoint opened: url=/home/x/.ethereum/ropsten/geth.ipc
 //
 pub struct EthClient {
+    // main_keypair (private, public)
+    main_keypair: (String, String),
+    passphrase: String,
     socket_path: String,
     subscriptions: Arc<Mutex<Vec<String>>>,
     notify_channel: (
@@ -182,16 +185,41 @@ pub struct EthClient {
 }
 
 impl EthClient {
-    pub fn new(socket_path: String) -> Arc<Self> {
+    pub fn new(
+        socket_path: String,
+        passphrase: String,
+        main_keypair: (String, String),
+    ) -> Arc<Self> {
         let notify_channel = async_channel::unbounded();
         let subscriptions = Arc::new(Mutex::new(Vec::new()));
         Arc::new(Self {
+            main_keypair,
+            passphrase,
             socket_path,
             subscriptions,
             notify_channel,
         })
     }
 
+    async fn send_eth_to_main_wallet(&self, acc: &str, amount: BigUint) -> Result<()> {
+
+        debug!(target: "ETH BRIDGE", "Send eth to main wallet");
+
+        let tx = EthTx::new(
+            acc,
+            &self.main_keypair.1,
+            None,
+            None,
+            Some(amount),
+            None,
+            None,
+        );
+
+        self.send_transaction(&tx, &self.passphrase).await?;
+
+        Ok(())
+    }
+
     async fn handle_subscribe_request(
         self: Arc<Self>,
         addr: String,
@@ -236,7 +264,9 @@ impl EthClient {
             ));
         }
 
-        let amnt = current_balance - prev_balance;
+        let received_balance = current_balance - prev_balance;
+
+        let received_balance_ui = received_balance.clone() / u64::pow(10, decimals as u32);
 
         send_notification
             .send(TokenNotification {
@@ -244,16 +274,20 @@ impl EthClient {
                 token_id: generate_id(ETH_NATIVE_TOKEN_ID, &NetworkName::Ethereum)?,
                 drk_pub_key,
                 // TODO FIX
-                received_balance: amnt.to_u64_digits()[0],
+                received_balance: received_balance.to_u64_digits()[0],
                 decimals: decimals as u16,
             })
             .await
             .map_err(Error::from)?;
 
+        self.send_eth_to_main_wallet(&addr, received_balance).await?;
+
+        debug!(target: "ETH BRIDGE", "Received {} eth", received_balance_ui );
+
         Ok(())
     }
 
-    async fn unsubscribe(self: Arc<Self>, pubkey: &String) {
+    async fn unsubscribe(&self, pubkey: &String) {
         let mut subscriptions = self.subscriptions.lock().await;
         let index = subscriptions.iter().position(|p| p == pubkey);
         if let Some(ind) = index {
@@ -355,15 +389,15 @@ impl NetworkClient for EthClient {
     ) -> Result<TokenSubscribtion> {
         let private_key = generate_privkey();
 
-        // TODO fix
-        let addr: String = self
-            .import_privkey(&private_key, "testpass")
-            .await?
-            .as_str()
-            .unwrap()
-            .to_string();
+        let addr = self.import_privkey(&private_key, &self.passphrase).await?;
+
+        let address: String = if addr.as_str().is_some() {
+            addr.as_str().unwrap().to_string()
+        } else {
+            return Err(Error::from(EthFailed::ImportPrivateError));
+        };
 
-        let addr_cloned = addr.clone();
+        let addr_cloned = address.clone();
         executor
             .spawn(async move {
                 let result = self
@@ -379,7 +413,7 @@ impl NetworkClient for EthClient {
 
         Ok(TokenSubscribtion {
             private_key,
-            public_key: addr,
+            public_key: address,
         })
     }
 
@@ -412,10 +446,30 @@ impl NetworkClient for EthClient {
 
     async fn send(
         self: Arc<Self>,
-        _address: Vec<u8>,
+        address: Vec<u8>,
         _mint: Option<String>,
-        _amount: u64,
+        amount: u64,
     ) -> Result<()> {
+        // Recipient address
+        let dest: String = deserialize(&address)?;
+
+        let decimals = 18;
+
+        // reverse truncate
+        let amount = truncate(amount, decimals as u16, 8)?;
+
+        let tx = EthTx::new(
+            &self.main_keypair.1,
+            &dest,
+            None,
+            None,
+            Some(BigUint::from(amount)),
+            None,
+            None,
+        );
+
+        self.send_transaction(&tx, &self.passphrase).await?;
+
         Ok(())
     }
 }
@@ -431,6 +485,7 @@ pub enum EthFailed {
     MintIsNotValid(String),
     JsonError(String),
     ParseError(String),
+    ImportPrivateError,
 }
 
 impl std::error::Error for EthFailed {}
@@ -462,6 +517,9 @@ impl std::fmt::Display for EthFailed {
             EthFailed::JsonError(i) => {
                 write!(f, "JsonError: {}", i)
             }
+            EthFailed::ImportPrivateError => {
+                write!(f, "Unable to derive address from private key")
+            }
             EthFailed::EthClientError(i) => {
                 write!(f, "Eth client error: {}", i)
             }