WTQRUTW5K7IQ6V65XFTYTH4LBJA23GRZKJGWD4X265TWB5Q4XTPAC
3IHKBPMSZU7SMYZFDWNHOVX7C2FPGOYR4D45BOQE5EF4JR4I7CWQC
2ZVBF5CFNCLOMSEINEDT45GB3QTNLGFNVTXZIA4FRYSCVPUD5QIQC
O7Q6BARE5TBHLUUYBTIVTOE373NLQUOQTPYGQKQWNDNUA4ZLMCNAC
2SQFSBLL73SZQFVNRGAJJ6DWJC7PH423NCT3LNDP5BCNFGFQK4CQC
36H3LIVEN7MC5BEQ3VFCNSXCMT7TBDOVEZXRJJKMQDFDBY53STGAC
HAVWPOXJXKLKF6P4ATMK52LEVARG4UURFFGCFN5EA4ZMF4JZGARAC
WLOVZ5OJEFQG57LMUNNIFHX6E7J5OZ6L2HEKY3N7KNNSLWMP2I4AC
WW3R2OTSI3NJJP2HXQ7QHBGYOO3NVS2NM3OQBDTLX5JQ3Z2DO7NAC
SGRGGOQHQZHXBJ2W6YQIHFGSX3L2LW43T6GEYLF3KFMKKQ3EISQQC
XWWGLD7EDPEQVJL57RRGPKYHEQCJIJAPGMKI3S62QZOLR6ODKQRAC
3DMSJR64RXGFQMHBPJ3RS7GYR537WISXHNEVQY63S7WFNSK6EM3AC
use std::collections::LinkedList;
use std::io;
use rand::{thread_rng, Rng};
use rand::distributions::Alphanumeric;
use openssl::sign::{Signer, Verifier};
use openssl::ec::{EcKey, EcGroup, EcGroupRef};
use openssl::pkey::{ PKey, Private };
use openssl::hash::MessageDigest;
use openssl::nid::Nid;
pub struct RFKPOSImpl {}
pub struct RFKPOSImpl {
db: Arc<Mutex<Database>>,
tokens: Arc<Mutex<LinkedList<String>>>,
}
pub struct DataValidator {
group: EcGroup,
key_priv: PKey<Private>,
}
impl DataValidator {
pub fn new() -> Result<Self, io::Error> {
let group = EcGroup::from_curve_name(Nid::SECP256K1)?;
let key = EcKey::generate(group.as_ref())?;
let key_priv = PKey::from_ec_key(key)?;
// let signer = Signer::new(MessageDigest::sha256(), &key_priv.as_ref()).unwrap();
Ok(Self { group: group, key_priv: key_priv })
}
}
fn new_token(tokens: Arc<Mutex<LinkedList<String>>>) -> String {
let new_token: String = thread_rng().sample_iter(Alphanumeric).take(32).map(char::from).collect();
let mut tokens = tokens.lock().unwrap();
tokens.push_back(new_token.clone());
while tokens.len() > 100 { tokens.pop_front(); }
new_token
}
async fn new_transaction(&self, request: Request<Transaction>) -> Result<Response<TransactionReturn>, Status> {
println!("Request from {:?}", request.remote_addr());
Ok(Response::new(TransactionReturn { return_value: Some(ReturnValue::Err(Error { message: "Not implemented".to_string(), prio: ErrorPriority::ErrCritical as i32 })) }))
async fn create(&self, request: Request<CreateTransaction>) -> Result<Response<TransactionReturn>, Status> {
let remote_addr = request.remote_addr();
let data = request.into_inner();
println!("Request from {:?} {:?}", remote_addr, data);
let data_validator = DataValidator::new();
let transaction = data.transaction.ok_or(Status::invalid_argument("transaction not specified"))?;
let data = transaction.data.ok_or(io::Error::new(io::ErrorKind::NotFound, "No transaction data found."))?;
let tid = data.tid;
self.db.lock().unwrap().transactions.insert(tid, transaction);
Ok(Response::new(TransactionReturn {
token: new_token(self.tokens.clone()),
tid: tid,
}))
rpc NewTransaction(Transaction) returns (TransactionReturn);
rpc LastTransaction(Login) returns (TransactionReturn);
rpc Create(CreateTransaction) returns (TransactionReturn);
rpc Get(GetTransaction) returns (TransactionReturn);
}
message GetTransaction {
string token = 1;
optional uint64 tid = 2;
string signature = 3;
}
message CreateTransaction {
string token = 1;
Transaction transaction = 2;
string signature = 3;
}
message TransactionData {
Timestamp ts = 1;
Timestamp valid_until = 2;
optional uint64 customer = 3; // customer tid
optional Money discount = 4;
repeated TransactionEntry entry = 5;
}
message Invalidate {
optional string comment = 2;
repeated uint64 invalidate = 3; // tid of transaction to invalidate
}
message SellTransaction {
TransactionData data = 1;
optional Invalidate invalidate = 2;
message RentTransaction {
TransactionData data = 1;
optional Invalidate invalidate = 2;
message Purchase {
Timestamp ts = 1;
PurchaseType purchase_type = 2;
optional Timestamp valid_until = 3;
optional uint64 customer = 4; // customer tid
optional Money discount = 5;
repeated PurchaseEntry entry = 6;
repeated uint64 invalidate = 7; // tid of transaction to invalidate
optional string comment = 8;