cashierd: send drk coins once received a notification from bridge

This commit is contained in:
ghassmo
2021-09-30 19:24:02 +03:00
parent e6834ea5b1
commit fbafdfe8c2
8 changed files with 97 additions and 48 deletions

View File

@@ -120,10 +120,11 @@ impl Cashierd {
for (network, _) in features.iter() {
let keypairs_to_watch = cashier_wallet.get_deposit_token_keys_by_network(&network)?;
for (private_key, public_key, _token_id, mint_address) in keypairs_to_watch {
for (drk_pub_key, private_key, public_key, _token_id, mint_address) in keypairs_to_watch
{
let bridge = bridge.clone();
let bridge_subscribtion = bridge.subscribe(Some(mint_address)).await;
let bridge_subscribtion = bridge.subscribe(drk_pub_key, Some(mint_address)).await;
bridge_subscribtion
.sender
@@ -157,8 +158,7 @@ impl Cashierd {
// send a request to bridge to send equivalent amount of
// received drk coin to token publickey
if let Some((addr, network, _token_id, mint_address)) = token {
let bridge_subscribtion = bridge.subscribe(Some(mint_address)).await;
let bridge_subscribtion = bridge.subscribe(drk_pub_key, Some(mint_address)).await;
bridge_subscribtion
.sender
@@ -175,7 +175,6 @@ impl Cashierd {
if error_code == 0 {
match res.payload {
bridge::BridgeResponsePayload::Send => {
// TODO Send the received coins to the main address
cashier_wallet.confirm_withdraw_key_record(&addr, &network)?;
}
_ => {}
@@ -227,7 +226,7 @@ impl Cashierd {
.get_deposit_token_keys_by_dkey_public(&drk_pub_key, &network)?;
let bridge = self.bridge.clone();
let bridge_subscribtion = bridge.subscribe(mint_address_opt).await;
let bridge_subscribtion = bridge.subscribe(drk_pub_key, mint_address_opt).await;
if check.is_empty() {
bridge_subscribtion
@@ -458,31 +457,41 @@ impl Cashierd {
let cashier_wallet = self.cashier_wallet.clone();
let bridge = self.bridge.clone();
let listen_for_receiving_coins_task = smol::spawn(async move {
let listen_for_receiving_coins_task: smol::Task<Result<()>> = smol::spawn(async move {
loop {
Self::listen_for_receiving_coins(
bridge.clone(),
cashier_wallet.clone(),
recv_coin.clone(),
)
.await
.expect(" listen for receiving coins");
.await?;
}
});
let bridge2 = self.bridge.clone();
let listen_for_notification_from_bridge_task = smol::spawn(async move {
loop {
if let Some(token_notification) = bridge2.clone().listen().await {
let token_notification =
token_notification.expect("listen for notification from bridge");
let client2 = self.client.clone();
let listen_for_notification_from_bridge_task: smol::Task<Result<()>> = smol::spawn(
async move {
loop {
if let Some(token_notification) = bridge2.clone().listen().await {
let token_notification = token_notification?;
debug!(target: "CASHIER DAEMON", "Notification from birdge: {:?}", token_notification);
debug!(target: "CASHIER DAEMON", "Notification from birdge: {:?}", token_notification);
// TODO should send drk coins
client2
.lock()
.await
.send(
token_notification.drk_pub_key,
token_notification.received_balance,
token_notification.token_id,
true,
)
.await?;
}
}
}
});
},
);
let cfg = RpcServerConfig {
socket_addr: self.config.rpc_listen_address.clone(),

View File

@@ -17,9 +17,7 @@ use drk::{
rpcserver::{listen_and_serve, RequestHandler, RpcServerConfig},
},
serial::{deserialize, serialize},
util::{
expand_path, join_config_path, parse_network, parse_wrapped_token, search_id,
},
util::{expand_path, join_config_path, parse_network, parse_wrapped_token, search_id},
wallet::WalletDb,
Result,
};
@@ -78,7 +76,8 @@ impl Darkfid {
expand_path(&config.spend_params_path.clone())?,
),
wallet.clone(),
).await?;
)
.await?;
let client = Arc::new(Mutex::new(client));
@@ -334,10 +333,11 @@ impl Darkfid {
let token_id = parse_wrapped_token(token)?;
let address = bs58::decode(&address).into_vec()?;
let address: jubjub::SubgroupPoint = deserialize(&address)?;
// TODO FIX THE AMOUNT
self.client
.lock()
.await
.transfer(token_id, address, amount)
.transfer(token_id, address, amount as u64)
.await?;
Ok(())
}

View File

@@ -112,14 +112,13 @@ impl Client {
&mut self,
asset_id: jubjub::Fr,
pub_key: jubjub::SubgroupPoint,
// TODO: FIX THIS
amount: f64,
amount: u64,
) -> Result<()> {
if amount <= 0.0 {
if amount <= 0 {
return Err(ClientFailed::InvalidAmount(amount as u64).into());
}
self.send(pub_key, amount as u64, asset_id, false).await?;
self.send(pub_key, amount, asset_id, false).await?;
Ok(())
}
@@ -150,7 +149,7 @@ impl Client {
let mut outputs: Vec<tx::TransactionBuilderOutputInfo> = vec![];
if clear_input {
let signature_secret = self.state.wallet.get_keypairs()?[0].private;
let signature_secret = self.main_keypair.private;
let input = tx::TransactionBuilderClearInputInfo {
value,
asset_id,

View File

@@ -50,8 +50,8 @@ pub struct TokenSubscribtion {
#[derive(Debug)]
pub struct TokenNotification {
pub network: NetworkName,
pub asset_id: jubjub::Fr,
pub secret_key: Vec<u8>,
pub token_id: jubjub::Fr,
pub drk_pub_key: jubjub::SubgroupPoint,
pub received_balance: u64,
}
@@ -93,12 +93,12 @@ impl Bridge {
.map(|o| o.map_err(Error::from))
}
pub async fn subscribe(self: Arc<Self>, mint: Option<String>) -> BridgeSubscribtion {
pub async fn subscribe(self: Arc<Self>, drk_pub_key: jubjub::SubgroupPoint, mint: Option<String>) -> BridgeSubscribtion {
debug!(target: "BRIDGE", "Start new subscription");
let (sender, req) = async_channel::unbounded();
let (rep, receiver) = async_channel::unbounded();
smol::spawn(self.listen_for_new_subscription(req, rep, mint)).detach();
smol::spawn(self.listen_for_new_subscription(req, rep, drk_pub_key, mint)).detach();
BridgeSubscribtion { sender, receiver }
}
@@ -107,6 +107,7 @@ impl Bridge {
self: Arc<Self>,
req: async_channel::Receiver<BridgeRequests>,
rep: async_channel::Sender<BridgeResponse>,
drk_pub_key: jubjub::SubgroupPoint,
mint: Option<String>,
) -> Result<()> {
debug!(target: "BRIDGE", "Listen for new subscription");
@@ -142,7 +143,7 @@ impl Bridge {
BridgeRequestsPayload::Watch(val) => match val {
Some((private_key, public_key)) => {
let pub_key = client
.subscribe_with_keypair(private_key, public_key, mint_address)
.subscribe_with_keypair(private_key, public_key, drk_pub_key, mint_address)
.await?;
let res = BridgeResponse {
error: BridgeResponseError::NoError,
@@ -151,7 +152,7 @@ impl Bridge {
rep.send(res).await?;
}
None => {
let sub = client.subscribe(mint_address).await?;
let sub = client.subscribe(drk_pub_key, mint_address).await?;
let res = BridgeResponse {
error: BridgeResponseError::NoError,
payload: BridgeResponsePayload::Watch(sub.secret_key, sub.public_key),
@@ -175,13 +176,14 @@ impl Bridge {
#[async_trait]
pub trait NetworkClient {
async fn subscribe(self: Arc<Self>, mint: Option<String>) -> Result<TokenSubscribtion>;
async fn subscribe(self: Arc<Self>, drk_pub_key: jubjub::SubgroupPoint, mint: Option<String>) -> Result<TokenSubscribtion>;
// should check if the keypair in not already subscribed
async fn subscribe_with_keypair(
self: Arc<Self>,
private_key: Vec<u8>,
public_key: Vec<u8>,
drk_pub_key: jubjub::SubgroupPoint,
mint: Option<String>,
) -> Result<String>;

View File

@@ -149,7 +149,11 @@ impl BtcClient {
#[async_trait]
impl NetworkClient for BtcClient {
async fn subscribe(self: Arc<Self>, _mint: Option<String>) -> Result<TokenSubscribtion> {
async fn subscribe(
self: Arc<Self>,
_drk_pub_key: jubjub::SubgroupPoint,
_mint: Option<String>,
) -> Result<TokenSubscribtion> {
// Generate bitcoin keys
let btc_keys = BitcoinKeys::new(self.network)?;
let btc_privkey = btc_keys.clone();
@@ -174,6 +178,7 @@ impl NetworkClient for BtcClient {
self: Arc<Self>,
_private_key: Vec<u8>,
_public_key: Vec<u8>,
_drk_pub_key: jubjub::SubgroupPoint,
_mint: Option<String>,
) -> Result<String> {
// TODO this not implemented yet

View File

@@ -24,10 +24,13 @@ use tungstenite::Message;
use crate::rpc::{jsonrpc, jsonrpc::JsonResult, websockets};
use crate::serial::{deserialize, serialize, Decodable, Encodable};
use crate::util::{generate_id, NetworkName};
use crate::{Error, Result};
use super::bridge::{NetworkClient, TokenNotification, TokenSubscribtion};
pub const SOL_NATIVE_TOKEN_ID: &str = "So11111111111111111111111111111111111111112";
#[derive(Serialize)]
struct SubscribeParams {
encoding: Value,
@@ -85,6 +88,7 @@ impl SolClient {
async fn handle_subscribe_request(
self: Arc<Self>,
keypair: Keypair,
drk_pub_key: jubjub::SubgroupPoint,
mint: Option<Pubkey>,
) -> SolResult<()> {
debug!(target: "SOL BRIDGE", "handle_subscribe_request()");
@@ -200,11 +204,35 @@ impl SolClient {
if mint.is_some() {
let amnt = cur_balance - prev_balance;
let ui_amnt = amnt / u64::pow(10, decimals as u32);
self.notify_channel
.0
.send(TokenNotification {
network: NetworkName::Solana,
token_id: generate_id(&mint.unwrap().to_string())?,
drk_pub_key,
received_balance: amnt,
})
.await
.map_err(Error::from)?;
debug!(target: "SOL BRIDGE", "Received {} {:?} tokens", ui_amnt, mint.unwrap());
let _ = self.send_tok_to_main_wallet(&rpc, &mint.unwrap(), amnt, decimals, &keypair)?;
} else {
let amnt = cur_balance - prev_balance;
let ui_amnt = lamports_to_sol(amnt);
self.notify_channel
.0
.send(TokenNotification {
network: NetworkName::Solana,
token_id: generate_id(SOL_NATIVE_TOKEN_ID)?,
drk_pub_key,
received_balance: amnt,
})
.await
.map_err(Error::from)?;
debug!(target: "SOL BRIDGE", "Received {} SOL", ui_amnt);
let _ = self.send_sol_to_main_wallet(&rpc, amnt, &keypair)?;
}
@@ -329,7 +357,11 @@ impl SolClient {
#[async_trait]
impl NetworkClient for SolClient {
async fn subscribe(self: Arc<Self>, mint_address: Option<String>) -> Result<TokenSubscribtion> {
async fn subscribe(
self: Arc<Self>,
drk_pub_key: jubjub::SubgroupPoint,
mint_address: Option<String>,
) -> Result<TokenSubscribtion> {
let keypair = Keypair::generate(&mut OsRng);
let public_key = keypair.pubkey().to_string();
@@ -337,7 +369,7 @@ impl NetworkClient for SolClient {
let mint = self.check_mint_address(mint_address)?;
smol::spawn(self.handle_subscribe_request(keypair, mint)).detach();
smol::spawn(self.handle_subscribe_request(keypair, drk_pub_key, mint)).detach();
Ok(TokenSubscribtion {
secret_key,
@@ -350,6 +382,7 @@ impl NetworkClient for SolClient {
self: Arc<Self>,
private_key: Vec<u8>,
_public_key: Vec<u8>,
drk_pub_key: jubjub::SubgroupPoint,
mint_address: Option<String>,
) -> Result<String> {
let keypair: Keypair = deserialize(&private_key)?;
@@ -358,7 +391,7 @@ impl NetworkClient for SolClient {
let mint = self.check_mint_address(mint_address)?;
smol::spawn(self.handle_subscribe_request(keypair, mint)).detach();
smol::spawn(self.handle_subscribe_request(keypair, drk_pub_key, mint)).detach();
Ok(public_key)
}

View File

@@ -305,11 +305,11 @@ impl CashierDb {
Ok(keys)
}
// return private key, public key, token_id, and mint_address as a tuple
// return drk_pub_key, private key, public key, token_id, and mint_address as a tuple
pub fn get_deposit_token_keys_by_network(
&self,
network: &NetworkName,
) -> Result<Vec<(Vec<u8>, Vec<u8>, jubjub::Fr, String)>> {
) -> Result<Vec<(jubjub::SubgroupPoint, Vec<u8>, Vec<u8>, jubjub::Fr, String)>> {
debug!(target: "CASHIERDB", "Check for existing dkey");
// open connection
let conn = Connection::open(&self.path)?;
@@ -320,25 +320,26 @@ impl CashierDb {
let confirm = self.get_value_serialized(&false)?;
let mut stmt = conn.prepare(
"SELECT token_key_private, token_key_public, token_id, mint_address
"SELECT d_pub_key, token_key_private, token_key_public, token_id, mint_address
FROM deposit_keypairs
WHERE network = :network
AND confirm = :confirm ;",
)?;
let keys_iter = stmt
.query_map(&[(":network", &network), (":confirm", &confirm)], |row| {
Ok((row.get(0)?, row.get(1)?, row.get(2)?, row.get(3)?))
Ok((row.get(0)?, row.get(1)?, row.get(2)?, row.get(3)?, row.get(4)?))
})?;
let mut keys = vec![];
for key in keys_iter {
let key = key?;
let private_key = key.0;
let pub_key = key.1;
let token_id: jubjub::Fr = self.get_value_deserialized(key.2)?;
let mint_address: String = self.get_value_deserialized(key.3)?;
keys.push((private_key, pub_key, token_id, mint_address));
let drk_pub_key: jubjub::SubgroupPoint = self.get_value_deserialized(key.0)?;
let private_key = key.1;
let pub_key = key.2;
let token_id: jubjub::Fr = self.get_value_deserialized(key.3)?;
let mint_address: String = self.get_value_deserialized(key.4)?;
keys.push((drk_pub_key, private_key, pub_key, token_id, mint_address));
}
Ok(keys)