Clean up merchant close and more tests

This commit is contained in:
J. Ayo Akinyele 2019-08-20 19:09:01 -04:00
parent ef3be30ea5
commit 68ed3a0711
4 changed files with 245 additions and 140 deletions

View File

@ -61,9 +61,9 @@ class Libbolt(object):
self.lib.ffishim_bidirectional_customer_close.argtypes = (c_void_p, c_void_p)
self.lib.ffishim_bidirectional_customer_close.restype = c_void_p
# self.lib.ffishim_bidirectional_merchant_close.argtypes = (c_void_p, c_void_p, c_void_p, c_void_p, c_void_p, c_void_p)
# self.lib.ffishim_bidirectional_merchant_close.restype = c_void_p
#
self.lib.ffishim_bidirectional_merchant_close.argtypes = (c_void_p, c_void_p, c_void_p, c_void_p)
self.lib.ffishim_bidirectional_merchant_close.restype = c_void_p
# self.lib.ffishim_bidirectional_resolve.argtypes = (c_void_p, c_void_p, c_void_p, c_void_p, c_void_p)
# self.lib.ffishim_bidirectional_resolve.restype = c_void_p
@ -79,78 +79,80 @@ class Libbolt(object):
def bidirectional_init_merchant(self, channel_state, b0_merch, name):
output_string = self.lib.ffishim_bidirectional_init_merchant(channel_state.encode(), b0_merch, name.encode())
output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8'))
return output_dictionary['channel_token'], output_dictionary['merch_wallet']
return output_dictionary['channel_token'], output_dictionary['merch_state']
def bidirectional_init_customer(self, channel_state, channel_token, b0_cust, b0_merch, name):
output_string = self.lib.ffishim_bidirectional_init_customer(channel_state.encode(), channel_token.encode(), b0_cust, b0_merch, name.encode())
output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8'))
return (output_dictionary['channel_token'], output_dictionary['cust_wallet'])
return (output_dictionary['channel_token'], output_dictionary['cust_state'])
# ESTABLISH PROTOCOL
def bidirectional_establish_customer_generate_proof(self, channel_token, cust_wallet):
output_string = self.lib.ffishim_bidirectional_establish_customer_generate_proof(channel_token.encode(), cust_wallet.encode())
def bidirectional_establish_customer_generate_proof(self, channel_token, cust_state):
output_string = self.lib.ffishim_bidirectional_establish_customer_generate_proof(channel_token.encode(), cust_state.encode())
output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8'))
return output_dictionary['channel_token'], output_dictionary['cust_wallet'], output_dictionary['com'], output_dictionary['com_proof']
return output_dictionary['channel_token'], output_dictionary['cust_state'], output_dictionary['com'], output_dictionary['com_proof']
def bidirectional_establish_merchant_issue_close_token(self, channel_state, com, com_proof, merch_wallet):
output_string = self.lib.ffishim_bidirectional_establish_merchant_issue_close_token(channel_state.encode(), com.encode(), com_proof.encode(), merch_wallet.encode())
def bidirectional_establish_merchant_issue_close_token(self, channel_state, com, com_proof, merch_state):
output_string = self.lib.ffishim_bidirectional_establish_merchant_issue_close_token(channel_state.encode(), com.encode(), com_proof.encode(), merch_state.encode())
output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8'))
return output_dictionary['close_token']
def bidirectional_establish_merchant_issue_pay_token(self, channel_state, com, merch_wallet):
output_string = self.lib.ffishim_bidirectional_establish_merchant_issue_pay_token(channel_state.encode(), com.encode(), merch_wallet.encode())
def bidirectional_establish_merchant_issue_pay_token(self, channel_state, com, merch_state):
output_string = self.lib.ffishim_bidirectional_establish_merchant_issue_pay_token(channel_state.encode(), com.encode(), merch_state.encode())
output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8'))
return output_dictionary['pay_token']
def bidirectional_establish_customer_verify_close_token(self, channel_state, cust_wallet, close_token):
output_string = self.lib.ffishim_bidirectional_verify_close_token(channel_state.encode(), cust_wallet.encode(), close_token.encode())
def bidirectional_establish_customer_verify_close_token(self, channel_state, cust_state, close_token):
output_string = self.lib.ffishim_bidirectional_verify_close_token(channel_state.encode(), cust_state.encode(), close_token.encode())
output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8'))
return output_dictionary['is_token_valid'], output_dictionary['channel_state'], output_dictionary['cust_wallet']
return output_dictionary['is_token_valid'], output_dictionary['channel_state'], output_dictionary['cust_state']
def bidirectional_establish_customer_final(self, channel_state, cust_wallet, pay_token):
output_string = self.lib.ffishim_bidirectional_establish_customer_final(channel_state.encode(), cust_wallet.encode(), pay_token.encode())
def bidirectional_establish_customer_final(self, channel_state, cust_state, pay_token):
output_string = self.lib.ffishim_bidirectional_establish_customer_final(channel_state.encode(), cust_state.encode(), pay_token.encode())
output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8'))
return output_dictionary['is_established'], output_dictionary['channel_state'], output_dictionary['cust_wallet']
return output_dictionary['is_established'], output_dictionary['channel_state'], output_dictionary['cust_state']
# PAY PROTOCOL
# generate payment proof
def bidirectional_pay_generate_payment_proof(self, channel_state, cust_wallet, amount):
output_string = self.lib.ffishim_bidirectional_pay_generate_payment_proof(channel_state.encode(), cust_wallet.encode(), amount)
def bidirectional_pay_generate_payment_proof(self, channel_state, cust_state, amount):
output_string = self.lib.ffishim_bidirectional_pay_generate_payment_proof(channel_state.encode(), cust_state.encode(), amount)
output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8'))
return output_dictionary['payment'], output_dictionary['cust_wallet']
return output_dictionary['payment'], output_dictionary['cust_state']
# verify payment proof
def bidirectional_pay_verify_payment_proof(self, channel_state, pay_proof, merch_wallet):
output_string = self.lib.ffishim_bidirectional_pay_verify_payment_proof(channel_state.encode(), pay_proof.encode(), merch_wallet.encode())
def bidirectional_pay_verify_payment_proof(self, channel_state, pay_proof, merch_state):
output_string = self.lib.ffishim_bidirectional_pay_verify_payment_proof(channel_state.encode(), pay_proof.encode(), merch_state.encode())
output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8'))
return (output_dictionary['close_token'], output_dictionary['merch_wallet'])
return (output_dictionary['close_token'], output_dictionary['merch_state'])
# generate revoke token
def bidirectional_pay_generate_revoke_token(self, channel_state, cust_wallet, new_cust_wallet, close_token):
output_string = self.lib.ffishim_bidirectional_pay_generate_revoke_token(channel_state.encode(), cust_wallet.encode(),
new_cust_wallet.encode(), close_token.encode())
def bidirectional_pay_generate_revoke_token(self, channel_state, cust_state, new_cust_state, close_token):
output_string = self.lib.ffishim_bidirectional_pay_generate_revoke_token(channel_state.encode(), cust_state.encode(),
new_cust_state.encode(), close_token.encode())
output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8'))
return output_dictionary['revoke_token'], output_dictionary['cust_wallet']
return output_dictionary['revoke_token'], output_dictionary['cust_state']
# verify revoke token
def bidirectional_pay_verify_revoke_token(self, revoke_token, merch_wallet):
output_string = self.lib.ffishim_bidirectional_pay_verify_revoke_token(revoke_token.encode(), merch_wallet.encode())
def bidirectional_pay_verify_revoke_token(self, revoke_token, merch_state):
output_string = self.lib.ffishim_bidirectional_pay_verify_revoke_token(revoke_token.encode(), merch_state.encode())
output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8'))
return (output_dictionary['pay_token'], output_dictionary['merch_wallet'])
return (output_dictionary['pay_token'], output_dictionary['merch_state'])
# CLOSE
def bidirectional_customer_close(self, channel_state, cust_wallet):
output_string = self.lib.ffishim_bidirectional_customer_close(channel_state.encode(), cust_wallet.encode())
def bidirectional_customer_close(self, channel_state, cust_state):
output_string = self.lib.ffishim_bidirectional_customer_close(channel_state.encode(), cust_state.encode())
output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8'))
return output_dictionary['cust_close']
return output_dictionary.get('cust_close')
def bidirectional_merchant_close(self, channel_state, channel_token, cust_close, merch_state):
output_string = self.lib.ffishim_bidirectional_merchant_close(channel_state.encode(), channel_token.encode(),
cust_close.encode(), merch_state.encode())
output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8'))
return (output_dictionary.get('wpk'), output_dictionary.get('revoke_token'), output_dictionary.get('error'))
# def bidirectional_merchant_refund(self, pp, channel, channel_token, merch_data, channel_closure, revoke_token):
# output_string = self.lib.ffishim_bidirectional_merchant_refund(pp.encode(), channel.encode(), channel_token.encode(), merch_data.encode(), channel_closure.encode(), revoke_token.encode())
# output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8'))
# return (output_dictionary['rc_m'], output_dictionary['state'])
#
# def bidirectional_resolve(self, pp, cust_data, merch_data, cust_closure, merch_closure):
# output_string = self.lib.ffishim_bidirectional_resolve( pp.encode(), cust_data.encode(), merch_data.encode(), cust_closure.encode(), merch_closure.encode())
@ -203,28 +205,28 @@ channel_state = libbolt.channel_setup("My New Channel A")
print("channel state new: ", channel_state)
(channel_token, merch_wallet) = libbolt.bidirectional_init_merchant(channel_state, b0_merch, "Bob")
(channel_token, merch_state) = libbolt.bidirectional_init_merchant(channel_state, b0_merch, "Bob")
print("merch_wallet: ", len(merch_wallet))
print("merch_state: ", len(merch_state))
#print("channel_token: ", type(_channel_token))
(channel_token, cust_wallet) = libbolt.bidirectional_init_customer(channel_state, channel_token, b0_cust, b0_merch, "Alice")
print("cust_wallet: ", len(cust_wallet))
(channel_token, cust_state) = libbolt.bidirectional_init_customer(channel_state, channel_token, b0_cust, b0_merch, "Alice")
print("cust_state: ", len(cust_state))
(channel_token, cust_wallet, com, com_proof) = libbolt.bidirectional_establish_customer_generate_proof(channel_token, cust_wallet)
(channel_token, cust_state, com, com_proof) = libbolt.bidirectional_establish_customer_generate_proof(channel_token, cust_state)
print("com: ", com)
close_token = libbolt.bidirectional_establish_merchant_issue_close_token(channel_state, com, com_proof, merch_wallet)
close_token = libbolt.bidirectional_establish_merchant_issue_close_token(channel_state, com, com_proof, merch_state)
print("close token: ", close_token)
(is_token_valid, channel_state, cust_wallet) = libbolt.bidirectional_establish_customer_verify_close_token(channel_state, cust_wallet, close_token)
(is_token_valid, channel_state, cust_state) = libbolt.bidirectional_establish_customer_verify_close_token(channel_state, cust_state, close_token)
pay_token = libbolt.bidirectional_establish_merchant_issue_pay_token(channel_state, com, merch_wallet)
pay_token = libbolt.bidirectional_establish_merchant_issue_pay_token(channel_state, com, merch_state)
print("pay token: ", pay_token)
(is_channel_established, channel_state, cust_wallet) = libbolt.bidirectional_establish_customer_final(channel_state, cust_wallet, pay_token)
(is_channel_established, channel_state, cust_state) = libbolt.bidirectional_establish_customer_final(channel_state, cust_state, pay_token)
if is_channel_established:
print("updated cust_wallet: ", cust_wallet)
print("updated cust_state: ", cust_state)
else:
print("channel still not established. did you verify close token?")
@ -232,21 +234,24 @@ else:
print("Pay protocol...")
amount = 5
(payment_proof, new_cust_wallet) = libbolt.bidirectional_pay_generate_payment_proof(channel_state, cust_wallet, amount)
(payment_proof, new_cust_state) = libbolt.bidirectional_pay_generate_payment_proof(channel_state, cust_state, amount)
print("Pay proof: ", len(payment_proof))
print("new cust wallet: ", new_cust_wallet)
print("new cust wallet: ", new_cust_state)
print("<========================================>")
(new_close_token, merch_wallet) = libbolt.bidirectional_pay_verify_payment_proof(channel_state, payment_proof, merch_wallet)
(new_close_token, merch_state) = libbolt.bidirectional_pay_verify_payment_proof(channel_state, payment_proof, merch_state)
print("Close token: ", new_close_token)
print("<========================================>")
(revoke_token, cust_wallet) = libbolt.bidirectional_pay_generate_revoke_token(channel_state, cust_wallet, new_cust_wallet, new_close_token)
(revoke_token, cust_state) = libbolt.bidirectional_pay_generate_revoke_token(channel_state, cust_state, new_cust_state, new_close_token)
print("Revoke token: ", revoke_token)
(pay_token, merch_wallet) = libbolt.bidirectional_pay_verify_revoke_token(revoke_token, merch_wallet)
(pay_token, merch_state) = libbolt.bidirectional_pay_verify_revoke_token(revoke_token, merch_state)
print("Pay token: ", pay_token)
cust_close_msg = libbolt.bidirectional_customer_close(channel_state, cust_wallet)
print("Cust close msg: ", cust_close_msg)
cust_close = libbolt.bidirectional_customer_close(channel_state, cust_state)
print("Cust close msg: ", cust_close)
print("<========================================>")
merch_close_tokens = libbolt.bidirectional_merchant_close(channel_state, channel_token, cust_close, merch_state)
print("Merch close tokens: ", merch_close_tokens)

View File

@ -12,6 +12,7 @@ pub mod ffishim {
use std::ffi::{CStr, CString};
use std::str;
use std::mem;
use bidirectional::ChannelcloseC;
fn error_message(s: String) -> *mut c_char {
let ser = ["{\'error\':\'", serde_json::to_string(&s).unwrap().as_str(), "\'}"].concat();
@ -324,34 +325,32 @@ pub mod ffishim {
cser.into_raw()
}
#[no_mangle]
pub extern fn ffishim_bidirectional_merchant_close(ser_channel_state: *mut c_char, ser_channel_token: *mut c_char,
ser_cust_close: *mut c_char, ser_merch_state: *mut c_char) -> *mut c_char {
// Deserialize the channel state
let channel_state: bidirectional::ChannelState<Bls12> = deserialize_object(ser_channel_state);
// Deserialize the channel token
let mut channel_token: bidirectional::ChannelToken<Bls12> = deserialize_object(ser_channel_token);
// Deserialize the customer close structure
let cust_close: bidirectional::ChannelcloseC<Bls12> = deserialize_object(ser_cust_close);
// Deserialize the merch wallet
let mut merch_state: bidirectional::MerchantState<Bls12> = deserialize_object(ser_merch_state);
let option = bidirectional::merchant_close(&channel_state, &channel_token, &cust_close, &merch_state);
let keys = match option {
Ok(n) => n.unwrap(),
Err(err) => return error_message(err),
};
let ser = ["{\'wpk\':\'", serde_json::to_string(&keys.wpk).unwrap().as_str(),
"\', \'revoke_token\':\'", serde_json::to_string(&keys.revoke_token).unwrap().as_str(), "\'}"].concat();
let cser = CString::new(ser).unwrap();
cser.into_raw()
}
}
// #[no_mangle]
// pub extern fn ffishim_bidirectional_merchant_refund(serialized_pp: *mut c_char, serialized_channel: *mut c_char, serialized_channel_token: *mut c_char, serialized_merchant_data: *mut c_char, serialized_channel_closure: *mut c_char, serialized_revoke_token: *mut c_char) -> *mut c_char {
// // Deserialize the pp
// let deserialized_pp: bidirectional::PublicParams = deserialize_object(serialized_pp);
//
// // Deserialize the channel state
// let mut deserialized_channel_state: bidirectional::ChannelState = deserialize_object(serialized_channel);
//
// // Deserialize the channel token
// let deserialized_channel_token: bidirectional::ChannelToken = deserialize_object(serialized_channel_token);
//
// // Deserialize the merchant data
// let deserialized_merchant_data: bidirectional::InitMerchantData = deserialize_object(serialized_merchant_data);
//
// // Deserialize the closure
// let deserialized_channel_closure: bidirectional::ChannelclosureC = deserialize_object(serialized_channel_closure);
//
// // Deserialize the revoke_token
// let deserialized_revoke_token: secp256k1::Signature = deserialize_object(serialized_revoke_token);
//
// let rc_m = bidirectional::merchant_refute(&deserialized_pp, &mut deserialized_channel_state, &deserialized_channel_token, &deserialized_merchant_data, &deserialized_channel_closure, &deserialized_revoke_token);
// let ser = ["{\'rc_m\':\'", serde_json::to_string(&rc_m).unwrap().as_str(), "\', \'state\':\'", serde_json::to_string(&deserialized_channel_state).unwrap().as_str(), "\'}"].concat();
// let cser = CString::new(ser).unwrap();
// cser.into_raw()
// }
//
// #[no_mangle]
// pub extern fn ffishim_bidirectional_resolve(serialized_pp: *mut c_char, serialized_customer_data: *mut c_char, serialized_merchant_data: *mut c_char, serialized_closure_customer: *mut c_char, serialized_closure_merchant: *mut c_char) -> *mut c_char {
// // Deserialize the pp

View File

@ -140,16 +140,11 @@ pub mod bidirectional {
#[serde(bound(deserialize = "<E as ff::ScalarEngine>::Fr: serde::Deserialize<'de>, \
<E as pairing::Engine>::G1: serde::Deserialize<'de>"))]
pub struct ChannelcloseC<E: Engine> {
pub wpk: secp256k1::PublicKey,
pub message: wallet::Wallet<E>,
pub signature: cl::Signature<E>
}
#[derive(Clone)]
pub struct ChannelcloseM<E: Engine> {
pub message: util::RevokedMessage,
pub signature: cl::Signature<E>
}
#[derive(Clone, Serialize, Deserialize)]
#[serde(bound(serialize = "<E as ff::ScalarEngine>::Fr: serde::Serialize, \
<E as pairing::Engine>::G1: serde::Serialize, \
@ -288,6 +283,8 @@ pub mod bidirectional {
// if valid revoke_token is provided later for wpk, then release pay-token
let new_close_token = merch_state.verify_payment(csprng, &channel_state,
&payment.proof, &payment.com, &payment.wpk, payment.amount).unwrap();
// store the wpk since it has been revealed
update_merchant_state(&mut merch_state.keys, &payment.wpk, None);
return new_close_token;
}
@ -384,29 +381,32 @@ pub mod bidirectional {
let close_wallet = wallet.with_close(String::from("close"));
assert!(pk.verify(&cp.pub_params.mpk, &close_wallet, &close_token));
ChannelcloseC { message: wallet, signature: close_token }
ChannelcloseC { wpk: cust_state.wpk, message: wallet, signature: close_token }
}
fn exist_in_merchant_state<E: Engine>(db: &mut HashMap<String, PubKeyMap>, wpk: &secp256k1::PublicKey, rev: Option<secp256k1::Signature>) -> bool {
if db.is_empty() {
return false;
}
let fingerprint = util::compute_pub_key_fingerprint(wpk);
if db.contains_key(&fingerprint) {
let pub_key = db.get(&fingerprint).unwrap();
if pub_key.revoke_token.is_none() {
// let's just check the public key
return pub_key.wpk == *wpk;
}
if !rev.is_none() {
return pub_key.wpk == *wpk && pub_key.revoke_token.unwrap() == rev.unwrap();
}
return pub_key.wpk == *wpk;
}
return false;
}
// fn exist_in_merchant_state<E: Engine>(db: &HashMap<String, PubKeyMap>, wpk: &secp256k1::PublicKey, rev: Option<secp256k1::Signature>) -> (bool, Option<PubKeyMap>) {
// if db.is_empty() {
// return (false, None);
// }
//
// let fingerprint = util::compute_pub_key_fingerprint(wpk);
// if db.contains_key(&fingerprint) {
// let revoked_state = db.get(&fingerprint).unwrap();
//
//
//
// if revoked_state.revoke_token.is_none() {
// // let's just check the public key
// return (revoked_state.wpk == *wpk, None);
// }
// if !rev.is_none() {
// return (revoked_state.wpk == *wpk && pub_key.revoke_token.unwrap() == rev.unwrap(), None);
// }
// return (pub_key.wpk == *wpk, Some(pub_key));
// }
//
// return false;
// }
fn update_merchant_state(db: &mut HashMap<String, PubKeyMap>, wpk: &secp256k1::PublicKey, rev: Option<secp256k1::Signature>) {
let fingerprint = util::compute_pub_key_fingerprint(wpk);
@ -421,35 +421,49 @@ pub mod bidirectional {
}
///
/// merchant_refute - takes as input the public params, channel token, merchant's wallet,
/// channels tate, channel closure from customer, and revocation token.
/// Generates a channel closure message for merchant and updated merchant internal state.
/// merchant_close - takes as input the channel state, channel token, customer close msg/sig,
/// Returns tokens for merchant close transaction (only if customer close message is found to be a
/// double spend). If not, then None is returned.
///
pub fn merchant_refute<E: Engine>(channel_state: &mut ChannelState<E>,
channel_token: &ChannelToken<E>,
rc_c: &ChannelcloseC<E>, rv_token: &secp256k1::Signature) -> bool {
return true;
pub fn merchant_close<E: Engine>(channel_state: &ChannelState<E>,
channel_token: &ChannelToken<E>,
cust_close: &ChannelcloseC<E>,
merch_state: &MerchantState<E>) -> BoltResult<PubKeyMap> {
if (!channel_state.channel_established) {
return Err(String::from("merchant_close - Channel not established! Cannot generate channel closure message."));
}
let cp = channel_state.cp.as_ref().unwrap();
let pk = cp.pub_params.keypair.get_public_key(&cp.pub_params.mpk);
let mut wallet = cust_close.message.clone();
let close_wallet = wallet.with_close(String::from("close")).clone();
let close_token = cust_close.signature.clone();
let is_valid = pk.verify(&cp.pub_params.mpk, &close_wallet, &close_token);
if is_valid {
let wpk = cust_close.wpk;
// found the wpk, which means old close token
let fingerprint = util::compute_pub_key_fingerprint(&wpk);
if merch_state.keys.contains_key(&fingerprint) {
let revoked_state = merch_state.keys.get(&fingerprint).unwrap();
if !revoked_state.revoke_token.is_none() {
let revoke_token = revoked_state.revoke_token.unwrap().clone();
// verify the revoked state first before returning
let secp = secp256k1::Secp256k1::new();
let revoke_msg = RevokedMessage::new(String::from("revoked"), wpk.clone());
let msg = secp256k1::Message::from_slice(&revoke_msg.hash_to_slice()).unwrap();
// verify that the revocation token is valid
if secp.verify(&msg, &revoke_token, &wpk).is_ok() {
return Ok(Some(revoked_state.clone()));
}
}
return Err(String::from("merchant_close - Found wpk but could not find the revoke token. Merchant abort detected."));
}
return Err(String::from("merchant_close - Could not find entry for wpk & revoke token pair. Valid close!"));
}
Err(String::from("merchant_close - Customer close message not valid!"))
}
// rc_c: &ChannelclosureC, rv_token: &secp256k1::Signature) // -> ChannelclosureM {
// // for merchant => on input the merchant's current state S_old and a customer channel closure message,
// // outputs a merchant channel closure message rc_m and updated merchant state S_new
// let is_valid = cl::verify_d(&pp.cl_mpk, &t_c.pk, &rc_c.message.hash(), &rc_c.signature);
// if is_valid {
// let wpk = rc_c.message.wpk;
// let balance = rc_c.message.balance;
// if !exist_in_merchant_state(&state, &wpk, Some(*rv_token)) {
// // update state to include the user's wallet key
// assert!(update_merchant_state(state, &wpk, Some(*rv_token)));
// }
// let ser_rv_token = rv_token.serialize_compact();
// let rm = RevokedMessage::new(String::from("revoked"), wpk, Some(ser_rv_token));
// // sign the revoked message
// let signature = cl::sign_d(&pp.cl_mpk, &m_data.csk.sk, &rm.hash());
// return ChannelclosureM { message: rm, signature: signature };
// } else {
// panic!("Signature on customer closure message is invalid!");
// }
// }
}
#[cfg(all(test, feature = "unstable"))]
@ -468,6 +482,7 @@ mod tests {
use super::*;
use ff::Rand;
use pairing::bls12_381::{Bls12};
use rand::Rng;
fn setup_new_channel_helper(channel_state: &mut bidirectional::ChannelState<Bls12>,
init_cust_bal: i32, init_merch_bal: i32)
@ -636,10 +651,10 @@ mod tests {
assert!(cust_state.cust_balance == (b0_customer - total_owed) && cust_state.merch_balance == total_owed + b0_merchant);
}
let cust_close = bidirectional::customer_close(&channel_state, &cust_state);
let cust_close_msg = bidirectional::customer_close(&channel_state, &cust_state);
println!("Obtained the channel close message");
println!("{}", cust_close.message);
println!("{}", cust_close.signature);
println!("{}", cust_close_msg.message);
println!("{}", cust_close_msg.signature);
}
}
@ -664,7 +679,6 @@ mod tests {
assert!(channel_state.channel_established);
{
// make multiple payments in a loop
execute_payment_protocol_helper(&mut channel_state, &mut channel_token, &mut merch_state, &mut cust_state, payment_increment);
{
@ -676,6 +690,94 @@ mod tests {
}
}
#[test]
fn bidirectional_merchant_close_detects_double_spends() {
let mut rng = &mut rand::thread_rng();
let b0_customer = rng.gen_range(100, 1000);
let b0_merchant = 10;
let pay_increment = 20;
let mut channel_state = bidirectional::ChannelState::<Bls12>::new(String::from("Channel A -> B"), false);
channel_state.setup(&mut rng); // or load_setup params
let (mut channel_token, mut merch_state, mut cust_state) = setup_new_channel_helper( &mut channel_state, b0_customer, b0_merchant);
// run establish protocol for customer and merchant channel
execute_establish_protocol_helper(&mut channel_state, &mut channel_token, &mut merch_state, &mut cust_state);
assert!(channel_state.channel_established);
// let's make a few payments then exit channel (will post an old channel state
execute_payment_protocol_helper(&mut channel_state, &mut channel_token, &mut merch_state, &mut cust_state, pay_increment);
execute_payment_protocol_helper(&mut channel_state, &mut channel_token, &mut merch_state, &mut cust_state, pay_increment);
// let's close then move state forward
let old_cust_close_msg = bidirectional::customer_close(&channel_state, &cust_state);
execute_payment_protocol_helper(&mut channel_state, &mut channel_token, &mut merch_state, &mut cust_state, pay_increment);
execute_payment_protocol_helper(&mut channel_state, &mut channel_token, &mut merch_state, &mut cust_state, pay_increment);
let cur_cust_close_msg = bidirectional::customer_close(&channel_state, &cust_state);
let merch_close_result = bidirectional::merchant_close(&channel_state,
&channel_token,
&old_cust_close_msg,
&merch_state);
let merch_close_msg = match merch_close_result {
Ok(n) => n.unwrap(),
Err(err) => panic!("Merchant close msg: {}", err)
};
println!("Double spend attempt by customer! Evidence below...");
println!("Merchant close: wpk = {}", merch_close_msg.wpk);
println!("Merchant close: revoke_token = {}", merch_close_msg.revoke_token.unwrap());
}
#[test]
#[should_panic]
fn bidirectional_merchant_close_works() {
let mut rng = &mut rand::thread_rng();
let b0_customer = rng.gen_range(100, 1000);
let b0_merchant = 10;
let pay_increment = 20;
let mut channel_state = bidirectional::ChannelState::<Bls12>::new(String::from("Channel A -> B"), false);
channel_state.setup(&mut rng); // or load_setup params
let (mut channel_token, mut merch_state, mut cust_state) = setup_new_channel_helper( &mut channel_state, b0_customer, b0_merchant);
// run establish protocol for customer and merchant channel
execute_establish_protocol_helper(&mut channel_state, &mut channel_token, &mut merch_state, &mut cust_state);
assert!(channel_state.channel_established);
// let's make a few payments then exit channel (will post an old channel state
execute_payment_protocol_helper(&mut channel_state, &mut channel_token, &mut merch_state, &mut cust_state, pay_increment);
execute_payment_protocol_helper(&mut channel_state, &mut channel_token, &mut merch_state, &mut cust_state, pay_increment);
execute_payment_protocol_helper(&mut channel_state, &mut channel_token, &mut merch_state, &mut cust_state, pay_increment);
execute_payment_protocol_helper(&mut channel_state, &mut channel_token, &mut merch_state, &mut cust_state, pay_increment);
let cust_close_msg = bidirectional::customer_close(&channel_state, &cust_state);
let merch_close_result = bidirectional::merchant_close(&channel_state,
&channel_token,
&cust_close_msg,
&merch_state);
let merch_close_msg = match merch_close_result {
Ok(n) => n.unwrap(),
Err(err) => panic!("Merchant close msg: {}", err)
};
}
// fn execute_third_party_pay_protocol_helper(pp: &bidirectional::PublicParams,
// channel1: &mut bidirectional::ChannelState, channel2: &mut bidirectional::ChannelState,
// merch_keys: &cl::KeyPairD, merch1_data: &mut bidirectional::InitMerchantData,

View File

@ -119,7 +119,6 @@ pub fn hash_buffer_to_fr<'a, E: Engine>(prefix: &'a str, buf: &[u8; 64]) -> E::F
pub struct RevokedMessage {
pub msgtype: String,
pub wpk: secp256k1::PublicKey
//pub sig: Option<[u8; 64]> // represents revocation token serialized compact bytes
}
impl RevokedMessage {