def new_bgp_withdraw(): """ Create a new BGP Withdraw transaction. The AS node that makes the transaction signs it using its private key. """ values = request.get_json() # Check that required fields are in the posted data required = ['prefix', 'as_source'] if not all(k in values for k in required): return 'Missing values', 400 # Create a new transaction prefix = values['prefix'] as_source = values['as_source'] tran_time = time() # Transaction creation time new_trans = BGP_Withdraw(prefix, as_source, tran_time) trans_hash = new_trans.calculate_hash() signature = node_key.sign(trans_hash.encode(), '') new_trans.sign(signature) # Broadcast it to the rest of the network (to be mined later) blockchain.broadcast_transaction(new_trans) new_trans_dict = new_trans.return_transaction( ) # also validates the transaction if new_trans_dict is not None and check_withdraw(prefix, as_source): update_bgp_txids(as_source) pending_transactions.append(new_trans_dict) # to be mined later return 'New BGP Withdraw transaction created. It was also broadcasted to the network', 200
def mine(): """ Mines a new block. Adds a new block that include all the valid transactions to the chain if the mining was successful. """ blockchain.resolve_conflicts( ) # check the network before mining a new block check_prefixes() mutex.acquire() # lock if blockchain.check_before_mining: remove_pending_transactions() if len(pending_transactions) > 0: last_block = blockchain.get_last_block() # check critical region last_block_hash = last_block.hash check_lease() for i in range(len(pending_transactions)): # update txid_to_block with all the txids that are about to be mined tran = pending_transactions[i]['trans'] txid = tran['txid'] txid_to_block[txid] = len(blockchain.chain) block = Block(len(blockchain.chain), time(), pending_transactions, last_block_hash) print("Mining...") block.proof_of_work() block.mined_timestamp = time() block_hash = block.calculate_hash() signature = node_key.sign(block_hash.encode(), '') block.sign(signature) block.mined_by(my_ASN) blockchain.add_block(block) blockchain.state_update() blockchain.check_before_mining = False update_sum.clear() assign_sum.clear() assigned_prefixes.clear() assign_txids.clear() remove_pending_transactions() mutex.release() # unlock broadcast_resolve_message() # let everyone know that the chain has changed return "Mined one block", 200
def new_assign_transaction(): """ Create a new transaction. The AS node that makes the transaction signs it using its private key. """ values = request.get_json() # Check that required fields are in the posted data required = [ 'prefix', 'as_source', 'as_dest', 'source_lease', 'leaseDuration', 'transferTag', 'last_assign' ] if not all(k in values for k in required): return 'Missing values', 400 # Create a new transaction prefix = values['prefix'] as_source = values['as_source'] as_dest = values['as_dest'] source_lease = values['source_lease'] leaseDuration = values['leaseDuration'] transferTag = values['transferTag'] last_assign = values['last_assign'] tran_time = time() # Transaction creation time new_trans = AssignTransaction(prefix, as_source, as_dest, source_lease, leaseDuration, transferTag, tran_time, last_assign) trans_hash = new_trans.calculate_hash() signature = node_key.sign(trans_hash.encode(), '') new_trans.sign(signature) test_str = '{}{}{}'.format(as_source, as_dest.sort(), last_assign).encode() test_hash = hashlib.sha256(test_str).hexdigest() if test_hash in assign_txids: return 'Transaction was already made', 500 # don't include the same transaction multiple times in the chain # Broadcast it to the rest of the network (to be mined later) blockchain.broadcast_transaction(new_trans) new_trans_dict = new_trans.return_transaction( ) # also validates the transaction if new_trans_dict is not None: pending_transactions.append(new_trans_dict) # to be mined later my_assignments.add(trans_hash) assigned_prefixes.add(prefix) assign_txids.add(test_hash) return 'New Assign transaction created. It was also broadcasted to the network', 200
def check_revoke(self, transaction): """ Checks occasionally if a revocation of a prefix needs to happen It creates and broadcasts a new Revoke transaction for this prefix if true. """ from Transaction import RevokeTransaction as_source = transaction['input'][1] txid = transaction['txid'] new_revoke = RevokeTransaction(as_source, txid, time()) trans_hash = new_revoke.calculate_hash() signature = node_key.sign(trans_hash.encode(), '') new_revoke.sign(signature) new_revoke_dict = new_revoke.return_transaction() if new_revoke_dict is not None: pending_transactions.append(new_revoke_dict) self.broadcast_transaction(new_revoke) my_assignments.remove(txid)
def new_update_transaction(): """ Create a new Update transaction. The AS node that makes the transaction signs it using its private key. """ values = request.get_json() # Check that required fields are in the posted data required = ['as_source', 'assign_tran', 'new_lease'] if not all(k in values for k in required): return 'Missing values', 400 # Create a new transaction as_source = values['as_source'] assign_tran = values['assign_tran'] new_lease = values['new_lease'] tran_time = time() # Transaction creation time new_trans = UpdateTransaction(as_source, assign_tran, tran_time, new_lease) trans_hash = new_trans.calculate_hash() signature = node_key.sign(trans_hash.encode(), '') new_trans.sign(signature) # Broadcast it to the rest of the network (to be mined later) blockchain.broadcast_transaction(new_trans) new_trans_dict = new_trans.return_transaction( ) # also validates the transaction if new_trans_dict is not None: pending_transactions.append(new_trans_dict) # to be mined later return 'New Update transaction created. It was also broadcasted to the network', 200