Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ERC-20 payment driver: added network field to transaction #974

Merged
merged 1 commit into from
Jan 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions core/payment-driver/gnt/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ hex = "0.4"
lazy_static = "1.4"
log = "0.4.8"
num-bigint = "0.2"
num-derive = "0.3"
num-traits = "0.2"
maplit = "1.0"
r2d2 = "0.8"
rlp = "0.4"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
-- HACK: All this code below is just to drop column network from table gnt_driver_payment
-- HACK: All this code below is just to drop column network from tables gnt_driver_payment and gnt_driver_transaction

PRAGMA foreign_keys=off;

Expand Down Expand Up @@ -26,4 +26,28 @@ DROP TABLE gnt_driver_payment;

ALTER TABLE gnt_driver_payment_tmp RENAME TO gnt_driver_payment;

CREATE TABLE gnt_driver_transaction_tmp
(
tx_id VARCHAR(128) NOT NULL PRIMARY KEY,
sender VARCHAR(40) NOT NULL,
-- U256 in big endian hex
nonce VARCHAR(64) NOT NULL,
timestamp DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
status INTEGER NOT NULL,
tx_type INTEGER NOT NULL,
encoded VARCHAR (8000) NOT NULL,
signature VARCHAR (130) NOT NULL,
tx_hash VARCHAR(64),
FOREIGN KEY(status) REFERENCES gnt_driver_transaction_status (status_id),
FOREIGN KEY(tx_type) REFERENCES gnt_driver_transaction_type (type_id)
);

INSERT INTO gnt_driver_transaction_tmp(tx_id, sender, nonce, timestamp, status, tx_type, encoded, signature, tx_hash)
SELECT tx_id, sender, nonce, timestamp, status, tx_type, encoded, signature, tx_hash FROM gnt_driver_transaction;


DROP TABLE gnt_driver_transaction;

ALTER TABLE gnt_driver_transaction_tmp RENAME TO gnt_driver_transaction;

PRAGMA foreign_keys=on;
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
ALTER TABLE gnt_driver_payment ADD COLUMN network INTEGER NOT NULL DEFAULT 4; -- 4 is rinkeby's network ID

ALTER TABLE gnt_driver_transaction ADD COLUMN network INTEGER NOT NULL DEFAULT 4; -- 4 is rinkeby's network ID
20 changes: 16 additions & 4 deletions core/payment-driver/gnt/src/dao/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::models::{TransactionEntity, TransactionStatus};
use crate::schema::gnt_driver_transaction::dsl;

use crate::dao::DbResult;
use crate::networks::Network;
use ya_persistence::executor::{do_with_transaction, AsDao, PoolType};

#[allow(unused)]
Expand Down Expand Up @@ -44,25 +45,36 @@ impl<'c> TransactionDao<'c> {
.await
}

pub async fn get_used_nonces(&self, address: String) -> DbResult<Vec<String>> {
pub async fn get_used_nonces(
&self,
address: String,
network: Network,
) -> DbResult<Vec<String>> {
do_with_transaction(self.pool, move |conn| {
let nonces: Vec<String> = dsl::gnt_driver_transaction
.filter(dsl::sender.eq(address))
.filter(dsl::network.eq(network))
.select(dsl::nonce)
.load(conn)?;
Ok(nonces)
})
.await
}

pub async fn get_unconfirmed_txs(&self) -> DbResult<Vec<TransactionEntity>> {
self.get_by_status(TransactionStatus::Sent.into()).await
pub async fn get_unconfirmed_txs(&self, network: Network) -> DbResult<Vec<TransactionEntity>> {
self.get_by_status(TransactionStatus::Sent.into(), network)
.await
}

pub async fn get_by_status(&self, status: i32) -> DbResult<Vec<TransactionEntity>> {
pub async fn get_by_status(
&self,
status: i32,
network: Network,
) -> DbResult<Vec<TransactionEntity>> {
do_with_transaction(self.pool, move |conn| {
let txs: Vec<TransactionEntity> = dsl::gnt_driver_transaction
.filter(dsl::status.eq(status))
.filter(dsl::network.eq(network))
.load(conn)?;
Ok(txs)
})
Expand Down
42 changes: 28 additions & 14 deletions core/payment-driver/gnt/src/gnt/sender.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,23 +197,27 @@ impl TransactionSender {
let db = self.db.clone();
let client = self.ethereum_client.clone();
let address_str = crate::utils::addr_to_str(&address);
let network = self.network;

future::try_join(
async move {
Ok::<_, GNTDriverError>(
db.as_dao::<TransactionDao>()
.get_used_nonces(address_str)
.await?
.into_iter()
.map(u256_from_big_endian_hex)
.max(),
)
let db_nonce = db
.as_dao::<TransactionDao>()
.get_used_nonces(address_str, network)
.await?
.into_iter()
.map(u256_from_big_endian_hex)
.max();
log::trace!("DB nonce: {:?}", db_nonce);
Ok::<_, GNTDriverError>(db_nonce)
},
async move {
client
let client_nonce = client
.get_next_nonce(address)
.map_err(GNTDriverError::from)
.await
.await;
log::trace!("Client nonce: {:?}", client_nonce);
client_nonce
},
)
.and_then(|r| {
Expand Down Expand Up @@ -395,6 +399,9 @@ impl Handler<TxSave> for TransactionSender {
})
.collect::<Vec<_>>();

db_transactions
.iter()
.for_each(|tx| log::trace!("Creating db transaction: {:?}", tx));
let db = self.db.clone();
let fut = {
let db = db.clone();
Expand Down Expand Up @@ -434,7 +441,8 @@ impl Handler<TxSave> for TransactionSender {
confirmations: required_confirmations,
});
}
Err(_e) => {
Err(e) => {
log::error!("Error sending transaction: {:?}", e);
db.as_dao::<TransactionDao>()
.update_tx_status(tx_id, TransactionStatus::Failed.into())
.await
Expand Down Expand Up @@ -762,10 +770,11 @@ impl TransactionSender {
let db = self.db.clone();
let me = ctx.address();
let required_confirmations = self.required_confirmations;
let network = self.network;
let job = async move {
let txs = db
.as_dao::<TransactionDao>()
.get_unconfirmed_txs()
.get_unconfirmed_txs(network)
.await
.unwrap();
for tx in txs {
Expand Down Expand Up @@ -904,7 +913,7 @@ async fn process_payment(
},
)
.await?;
log::error!("NGNT transfer failed: {}", e);
log::error!("GLM transfer failed: {}", e);
return Err(e);
}
}
Expand Down Expand Up @@ -936,7 +945,12 @@ async fn transfer_gnt(
GNT_TRANSFER_GAS.into(),
);
let r = batch.send_to(tx_sender, sign_tx).await?;
Ok(r.into_iter().next().unwrap())
match r.into_iter().next() {
Some(tx) => Ok(tx),
None => Err(GNTDriverError::LibraryError(
"GLM transfer failed".to_string(),
)),
}
}

async fn notify_tx_confirmed(db: DbExecutor, tx_id: String) -> GNTDriverResult<()> {
Expand Down
3 changes: 3 additions & 0 deletions core/payment-driver/gnt/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#[macro_use]
extern crate diesel;

#[macro_use]
extern crate num_derive;

pub mod migrations {
#[derive(diesel_migrations::EmbedMigrations)]
struct _Dummy;
Expand Down
1 change: 1 addition & 0 deletions core/payment-driver/gnt/src/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ pub struct TransactionEntity {
pub encoded: String,
pub signature: String,
pub tx_hash: Option<String>,
pub network: Network,
}

#[derive(Queryable, Clone, Debug, Identifiable, Insertable, PartialEq)]
Expand Down
2 changes: 1 addition & 1 deletion core/payment-driver/gnt/src/networks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use std::fmt::{Display, Formatter, Result as FmtResult};
use std::str::FromStr;
use ya_core_model::payment::local as pay_srv;

#[derive(AsExpression, FromSqlRow, PartialEq, Debug, Clone, Copy)]
#[derive(AsExpression, FromSqlRow, PartialEq, Debug, Clone, Copy, FromPrimitive)]
#[sql_type = "Integer"]
pub enum Network {
Mainnet = 1,
Expand Down
1 change: 1 addition & 0 deletions core/payment-driver/gnt/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ table! {
encoded -> Text,
signature -> Text,
tx_hash -> Nullable<Text>,
network -> Integer,
}
}

Expand Down
6 changes: 4 additions & 2 deletions core/payment-driver/gnt/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
use crate::error::GNTDriverError;
use crate::GNTDriverResult;

use crate::models::{TransactionEntity, TransactionStatus, TxType};
use crate::networks::Network;
use crate::GNTDriverResult;
use bigdecimal::BigDecimal;
use chrono::{DateTime, Utc};
use ethereum_tx_sign::RawTransaction;
use ethereum_types::{Address, H160, H256, U256};
use futures3::{Future, FutureExt};
use num_bigint::ToBigInt;
use num_traits::FromPrimitive;
use sha3::{Digest, Sha3_512};
use std::pin::Pin;
use std::str::FromStr;
Expand Down Expand Up @@ -93,6 +94,7 @@ pub fn raw_tx_to_entity(
tx_type: tx_type.into(),
signature: hex::encode(signature),
tx_hash: None,
network: Network::from_u64(chain_id).unwrap(),
}
}

Expand Down
4 changes: 2 additions & 2 deletions core/payment/examples/debit_note_flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ async fn main() -> anyhow::Result<()> {
log::info!("Debit note accepted.");

log::info!("Waiting for payment...");
let timeout = Some(Duration::from_secs(300)); // Should be enough for GLM transfer
let timeout = Some(Duration::from_secs(1000)); // Should be enough for GLM transfer
let mut payments = provider
.get_payments(Some(&now), timeout, None, None)
.await?;
Expand Down Expand Up @@ -156,7 +156,7 @@ async fn main() -> anyhow::Result<()> {
log::info!("Debit note accepted.");

log::info!("Waiting for payment...");
let timeout = Some(Duration::from_secs(300)); // Should be enough for GLM transfer
let timeout = Some(Duration::from_secs(1000)); // Should be enough for GLM transfer
let mut payments = provider
.get_payments(Some(&now), timeout, None, args.app_session_id.clone())
.await?;
Expand Down
2 changes: 1 addition & 1 deletion core/payment/examples/invoice_flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ async fn main() -> anyhow::Result<()> {
log::debug!("events 2: {:?}", &invoice_events_accepted);

log::info!("Waiting for payment...");
let timeout = Some(Duration::from_secs(300)); // Should be enough for GLM transfer
let timeout = Some(Duration::from_secs(1000)); // Should be enough for GLM transfer
let mut payments = provider
.get_payments(Some(&now), timeout, None, args.app_session_id.clone())
.await?;
Expand Down