diff --git a/py/libbolt.py b/py/libbolt.py index ae61285..7c7d843 100644 --- a/py/libbolt.py +++ b/py/libbolt.py @@ -134,7 +134,7 @@ class Libbolt(object): 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_state']) + return (output_dictionary.get('close_token'), output_dictionary.get('merch_state')) # generate revoke token def bidirectional_pay_generate_revoke_token(self, channel_state, cust_state, new_cust_state, close_token): @@ -153,7 +153,8 @@ class Libbolt(object): def bidirectional_pay_verify_payment_token(self, channel_state, cust_state, pay_token): output_string = self.lib.ffishim_bidirectional_pay_verify_payment_token(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['cust_state'], output_dictionary['is_pay_valid']) + is_pay_valid = self._convert_boolean(output_dictionary.get('is_pay_valid')) + return (output_dictionary['cust_state'], is_pay_valid) # CLOSE diff --git a/py/tests.py b/py/tests.py index 8206f64..ab0e9ce 100644 --- a/py/tests.py +++ b/py/tests.py @@ -14,6 +14,11 @@ def malformed_token(token): updated_token[k] = v[:-4] + rand_hex(4) return json.dumps(updated_token) +def malformed_proof(proof): + bad_proof = proof.replace("0", "1") + bad_proof = bad_proof.replace("1", "2") + return bad_proof + class BoltEstablishTests(unittest.TestCase): def setUp(self): self.bolt = libbolt.Libbolt('target/{}/{}bolt.{}'.format(libbolt.mode, libbolt.prefix, libbolt.ext)) @@ -130,5 +135,66 @@ class BoltEstablishTests(unittest.TestCase): (is_channel_established, channel_state, cust_state) = self.bolt.bidirectional_establish_customer_final(self.channel_state, cust_state, malformed_pay_token) self.assertFalse(is_channel_established) +class BoltPayTests(unittest.TestCase): + def setUp(self): + """ + Setup init customer/merchant state and establish phase of Bolt protocol + :return: + """ + self.bolt = libbolt.Libbolt('target/{}/{}bolt.{}'.format(libbolt.mode, libbolt.prefix, libbolt.ext)) + self.channel_state = self.bolt.channel_setup("Test Channel") + self.b0_cust = 500 + self.b0_merch = 10 + (self.channel_token, self.merch_state) = self.bolt.bidirectional_init_merchant(self.channel_state, self.b0_merch, "Bob") + (self.channel_token, self.cust_state) = self.bolt.bidirectional_init_customer(self.channel_state, self.channel_token, + self.b0_cust, self.b0_merch, "Alice") + + (self.channel_token, self.cust_state, com, com_proof) = self.bolt.bidirectional_establish_customer_generate_proof(self.channel_token, self.cust_state) + + close_token = self.bolt.bidirectional_establish_merchant_issue_close_token(self.channel_state, com, com_proof, self.b0_cust, self.b0_merch, self.merch_state) + self.assertTrue(close_token is not None) + + (is_token_valid, self.channel_state, self.cust_state) = self.bolt.bidirectional_establish_customer_verify_close_token(self.channel_state, self.cust_state, close_token) + self.assertTrue(is_token_valid) + + pay_token = self.bolt.bidirectional_establish_merchant_issue_pay_token(self.channel_state, com, self.merch_state) + self.assertTrue(pay_token is not None) + + (is_channel_established, self.channel_state, self.cust_state) = self.bolt.bidirectional_establish_customer_final(self.channel_state, self.cust_state, pay_token) + + self.assertTrue(is_channel_established) + + def test_pay_protocol_works(self): + """ + Payment protocol works + :return: + """ + amount = 10 + (payment_proof, new_cust_state) = self.bolt.bidirectional_pay_generate_payment_proof(self.channel_state, self.cust_state, amount) + + (new_close_token, self.merch_state) = self.bolt.bidirectional_pay_verify_payment_proof(self.channel_state, payment_proof, self.merch_state) + + (revoke_token, self.cust_state) = self.bolt.bidirectional_pay_generate_revoke_token(self.channel_state, self.cust_state, new_cust_state, new_close_token) + + (pay_token, self.merch_state) = self.bolt.bidirectional_pay_verify_revoke_token(revoke_token, self.merch_state) + + (self.cust_state, is_pay_valid) = self.bolt.bidirectional_pay_verify_payment_token(self.channel_state, self.cust_state, pay_token) + self.assertTrue(is_pay_valid) + + def test_pay_protocol_bad_payment_proof_fails(self): + amount = 10 + (payment_proof, new_cust_state) = self.bolt.bidirectional_pay_generate_payment_proof(self.channel_state, self.cust_state, amount) + + bad_payment_proof = malformed_proof(payment_proof) + (new_close_token, self.merch_state) = self.bolt.bidirectional_pay_verify_payment_proof(self.channel_state, bad_payment_proof, self.merch_state) + self.assertTrue(new_close_token is None) + + def test_pay_protocol_bad_revoke_token_fails(self): + pass + + def test_pay_protocol_bad_payment_token_fails(self): + pass + + if __name__ == '__main__': unittest.main()