canceling transactions

This commit is contained in:
Marco Salazar 2022-08-18 23:05:04 +08:00
parent 6d5c0b6e1c
commit 8db2744b06
2 changed files with 172 additions and 4 deletions

View File

@ -111,8 +111,6 @@ class Slate(db.Model):
db.session.rollback() db.session.rollback()
return False return False
@classmethod @classmethod
def add(cls, slate, receivingAddress): def add(cls, slate, receivingAddress):
from funding.factory import db from funding.factory import db
@ -132,3 +130,73 @@ class Slate(db.Model):
except Exception as ex: except Exception as ex:
db.session.rollback() db.session.rollback()
raise raise
class Cancel(db.Model):
__tablename__ = "cancels"
id = db.Column(db.Integer, primary_key=True)
slate_id = db.Column(db.String())
# TODO: clear slatse that have been in the database past a certain time
posted_time = db.Column(db.DateTime)
receivingAddress = db.Column(db.String(52), nullable=False)
sendersAddress = db.Column(db.String(52), nullable=False)
def __init__(self, slate_id, receivingAddress, sendersAddress):
from funding.factory import bcrypt
self.slate_id = slate_id
self.receivingAddress = receivingAddress
self.sendersAddress = sendersAddress
self.posted_time = datetime.utcnow()
def __repr__(self):
return "<Cancel(slate_id='%s', receivingAddress='%s', sendersAddress='%s', posted_time='%s)>" % (
self.slate_id, self.receivingAddress, self.sendersAddress, self.posted_time)
@classmethod
def find_slate_ids(cls, address):
q = cls.query
q = q.filter(Cancel.receivingAddress == address)
result = q.all()
print(f'{result}')
list_slates = []
for slate_db in result:
list_slates.append({slate_db.slate_id: slate_db.sendersAddress})
return list_slates
@classmethod
def delete_slate_id(cls, address, slate_id):
q = cls.query
q = q.filter(and_(Cancel.receivingAddress == address, Cancel.slate_id == slate_id))
result = q.first()
if result is None:
print("none guy")
return True
try:
db.session.delete(result)
db.session.commit()
db.session.flush()
return True
except Exception as ex:
db.session.rollback()
return False
@classmethod
def add(cls, slate_id, receivingAddress, sendersAddress):
from funding.factory import db
try:
previous = cls.query.filter(Cancel.slate_id == slate_id).first()
if previous is not None:
print(previous)
print("was inputted before")
return
# put in new one
new_cancel_request = Cancel(slate_id=slate_id, receivingAddress=receivingAddress, sendersAddress=sendersAddress)
db.session.add(new_cancel_request)
db.session.commit()
db.session.flush()
return new_cancel_request
except Exception as ex:
db.session.rollback()
raise

View File

@ -8,7 +8,7 @@ import json
import settings import settings
from funding.factory import app, db, cache from funding.factory import app, db, cache
from funding.orm import Address, Slate from funding.orm import Address, Slate, Cancel
import secp256k1 import secp256k1
import base58 import base58
@ -89,7 +89,7 @@ def getSlates(receivingAddress, signature):
) )
def deleteSlate(receivingAddress, signature, slate): def deleteSlate(receivingAddress, signature, slate):
try: try:
if receivingAddress is None or signature is None: if slate is None or signature is None or receivingAddress is None:
return make_response(jsonify({'status': 'failure', 'error': str("missing correct arguments")})) return make_response(jsonify({'status': 'failure', 'error': str("missing correct arguments")}))
# Deserialize the base-58 address to an internal public key format # Deserialize the base-58 address to an internal public key format
@ -112,3 +112,103 @@ def deleteSlate(receivingAddress, signature, slate):
except Exception as ex: except Exception as ex:
print(f'{ex}') print(f'{ex}')
return make_response(jsonify({'status': 'failure', 'error': str(ex)})) return make_response(jsonify({'status': 'failure', 'error': str(ex)}))
@app.route('/postCancel', methods=['POST'])
@endpoint.api(
parameter('receivingAddress', type=str, required=True),
parameter('signature', type=str, required=True),
parameter('slate', type=str, required=True),
parameter('sendersAddress', type=str, required=True),
)
def postCancel(receivingAddress, signature, slate, sendersAddress):
try:
if sendersAddress is None or slate is None or signature is None or receivingAddress is None:
return make_response(jsonify({'status': 'failure', 'error': str("missing correct arguments")}))
# Deserialize the base-58 address to an internal public key format
# NOTE: This assumes that the network version (which is not part of the key) is exactly 2 bytes
public_key = secp256k1.PublicKey(base58.b58decode_check(sendersAddress)[2:], raw=True)
# Prepare the message bound to the signature: a domain separator and the encoded address
# For some reason, the original client code calls this the "challenge"
message = 'SubscribeRequest_' + sendersAddress
# Deserialize and verify the provided signature against the message and address public key
if not public_key.ecdsa_verify(message.encode(),
public_key.ecdsa_deserialize(bytes(bytearray.fromhex(signature)))):
return make_response(jsonify({'status': 'failure', 'error': str("bad signature")}))
try:
Cancel.add(receivingAddress=receivingAddress, slate_id=slate, sendersAddress=sendersAddress)
except Exception as ex:
print(f'{ex}')
return make_response(jsonify({'status': 'success'}))
except Exception as ex:
print(f'{ex}')
return make_response(jsonify({'status': 'failure', 'error': str(ex)}))
@app.route('/getCancels', methods=['POST'])
@endpoint.api(
parameter('receivingAddress', type=str, required=True),
parameter('signature', type=str, required=True),
)
def getCancels(receivingAddress, signature):
try:
if receivingAddress is None or signature is None:
return make_response(jsonify({'status': 'failure', 'error': str("missing correct arguments")}))
# Deserialize the base-58 address to an internal public key format
# NOTE: This assumes that the network version (which is not part of the key) is exactly 2 bytes
public_key = secp256k1.PublicKey(base58.b58decode_check(receivingAddress)[2:], raw=True)
# Prepare the message bound to the signature: a domain separator and the encoded address
# For some reason, the original client code calls this the "challenge"
message = 'SubscribeRequest_' + receivingAddress
# Deserialize and verify the provided signature against the message and address public key
if not public_key.ecdsa_verify(message.encode(),
public_key.ecdsa_deserialize(bytes(bytearray.fromhex(signature)))):
return make_response(jsonify({'status': 'failure', 'error': str("bad signature")}))
slates = Cancel.find_slate_ids(address=receivingAddress)
return make_response(jsonify({'status': 'success', 'canceled_slates': slates}))
except Exception as ex:
print(f'{ex}')
return make_response(jsonify({'status': 'failure', 'error': str(ex)}))
@app.route('/deleteCancels', methods=['POST'])
@endpoint.api(
parameter('receivingAddress', type=str, required=True),
parameter('signature', type=str, required=True),
parameter('slate', type=str, required=True)
)
def deleteCancels(receivingAddress, signature, slate):
try:
if slate is None or signature is None or receivingAddress is None:
return make_response(jsonify({'status': 'failure', 'error': str("missing correct arguments")}))
# Deserialize the base-58 address to an internal public key format
# NOTE: This assumes that the network version (which is not part of the key) is exactly 2 bytes
public_key = secp256k1.PublicKey(base58.b58decode_check(receivingAddress)[2:], raw=True)
# Prepare the message bound to the signature: a domain separator and the encoded address
# For some reason, the original client code calls this the "challenge"
message = 'SubscribeRequest_' + receivingAddress
# Deserialize and verify the provided signature against the message and address public key
if not public_key.ecdsa_verify(message.encode(),
public_key.ecdsa_deserialize(bytes(bytearray.fromhex(signature)))):
return make_response(jsonify({'status': 'failure', 'error': str("bad signature")}))
is_deleted = Cancel.delete_slate_id(address=receivingAddress, slate_id=slate)
return make_response(jsonify({'status': 'success', 'is_deleted': is_deleted}))
except Exception as ex:
print(f'{ex}')
return make_response(jsonify({'status': 'failure', 'error': str(ex)}))