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 tidoptional 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 tidoptional Money discount = 5;repeated PurchaseEntry entry = 6;repeated uint64 invalidate = 7; // tid of transaction to invalidateoptional string comment = 8;