Beispiel #1
0
 def handle_snapshot(self, message, initial=True):
     print('snapshot_id: {}'.format(message.snapshot_id))
     if not initial:
         print('From: {}'.format(message.branch_name))
     # Set marker
     marker = bank_pb2.Marker()
     marker.branch_name = self.name
     marker.snapshot_id = message.snapshot_id
     # Create local snapshot to send later
     stored_snapshot = bank_pb2.ReturnSnapshot()
     stored_snapshot.local_snapshot.snapshot_id = message.snapshot_id
     # Set balance of local snapshot and default value channel_states
     stored_snapshot.local_snapshot.balance = self.balance
     stored_snapshot.local_snapshot.channel_state[:] = [
         0 for _ in range(len(self.branches))
     ]
     print('Initial channel_state')
     print(stored_snapshot.local_snapshot.channel_state)
     # Store local snapshot which means it has seen snapshot_id
     self.snapshots[message.snapshot_id] = (stored_snapshot, True)
     self.channel_states[message.snapshot_id] = [
         0 for _ in range(len(self.branches))
     ]
     if not initial:
         incoming_channel_index = self.get_branch_index(message.branch_name)
         # Set incoming channel as empty for snapshot
         self.channel_states[
             message.snapshot_id][incoming_channel_index] = None
     new_message = bank_pb2.BranchMessage()
     new_message.marker.MergeFrom(marker)
     for sock in self.sockets:
         sock[1].acquire()
         self.message_socket(sock[0], new_message)
         sock[1].release()
    def __init__(self):
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.s.bind((socket.gethostname(), int(sys.argv[2])))
        self.s.listen(100)
        self.branch_names = []
        self.branch_ip = []
        self.branch_port = []
        self.balance = 0
        self.mutex = Lock()
        self.server_branch_Message = bank_pb2.BranchMessage()
        self.client_branch_Message = bank_pb2.BranchMessage()
        self.marker_Message = bank_pb2.Marker()
        self.local_snapshot_Message = bank_pb2.ReturnSnapshot.LocalSnapshot()
        self.my_name = ''
        self.sock_list = [self.s]
        self.sock_dict = {}
        self.sock_dict_rev = {}

        self.state = []
        self.rec = []
        self.fm = []
        self.channel_state = []
        self.m_rcvd = []
        self.m_rcvd_cnt = []
        self.m_sent = []
        self.msg_count = 0
        self.map = {}
        self.check_branch_names = []
        self.check_branch_ip = []
        self.check_branch_port = []
 def send_markers(self, snapshot_id):
     branch_msg = bank_pb2.BranchMessage()
     markr = bank_pb2.Marker()
     markr.snapshot_id = snapshot_id
     markr.branch_name = self.branch_name
     branch_msg.marker.CopyFrom(markr)
     for connections in self.connections:
         connections.sendall(branch_msg.SerializeToString())
Beispiel #4
0
    def handle_init_snapshot(cls, incoming_message):

        # Temporarily pause the money transfer
        MoneyTransferThread.set_enabled(False)

        # Grab the lock, since the current_snapshots data structure we modify ahead is shared between threads
        cls.marker_handler_lock.acquire()

        # Make sure that the new snapshot_id doesn't already exist
        snapshot_id = incoming_message.init_snapshot.snapshot_id
        if snapshot_id in cls.current_snapshots:
            print "ERROR! Got init snapshot again for snapshot id : " + str(
                snapshot_id)
            return

        print "Got init_snapshot msg (snapshot_id: " + str(snapshot_id) + ")"

        # Record local state
        current_balance = BankVault.get_balance()
        state = {"local": current_balance}
        cls.current_snapshots[snapshot_id] = state

        # Create marker message
        marker_msg = bank_pb2.Marker()
        marker_msg.snapshot_id = snapshot_id

        pb_msg = bank_pb2.BranchMessage()
        pb_msg.marker.CopyFrom(marker_msg)

        # Send marker message to everyone else
        total_peers = ThreadPool.get_thread_count()
        for i in range(total_peers):
            a_friend = ThreadPool.get_thread(i)

            if not a_friend:
                continue

            print "Sending marker message to : " + str(a_friend.remote_branch_name) + " (snapshot_id: "\
                  + str(snapshot_id) + ")"
            a_friend.send_msg_to_remote(pb_msg)

            # Start recording all incoming activity
            a_friend.add_recorder(snapshot_id)

        # Release the lock, we're done modifying the shared data structure
        cls.marker_handler_lock.release()

        # Resume the money transfer thread
        MoneyTransferThread.set_enabled(True)
Beispiel #5
0
    def SendMarkers(self,snapshot_id):
	global branhList
	global moneyTransfer
	global branchName
	moneyTransfer  = False
	markerMessage = bank_pb2.Marker()
        markerMessage.snapshot_id = snapshot_id
	markerMessage.src_branch = branchName
        branchMessage = bank_pb2.BranchMessage()
        branchMessage.marker.CopyFrom(markerMessage)
	for branch in branhList:
        	markerSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                markerSocket.connect((branch.ip, branch.port))
                markerSocket.sendall(pickle.dumps(branchMessage))
                markerSocket.close()
	moneyTransfer  = True
Beispiel #6
0
    def sendMarkerToAll(self, snapshot_id):
        # Send a Marker message to all branches
        for port in self.branches.keys():
            if port == self.port:
                continue

            # Create empty BranchMessage
            bm = bank_pb2.BranchMessage()

            marker = bank_pb2.Marker()
            marker.send_branch = self.name
            marker.snapshot_id = snapshot_id

            # Attach Marker to BranchMessage
            bm.marker.CopyFrom(marker)

            sent = self.sendMessage(bm, port)
            if sent:
                print('Sent Marker to port %i from port %i' %
                      (port, self.port))
def receiver(client_socket):
    global balance
    global branches_all
    global branch_soc_list
    global curr_snap_id
    global this_branch
    global marker_count
    global RECORD

    while 1:
        received_message = client_socket.recv(1024)
        data = bank_pb2.BranchMessage()
        data.ParseFromString(received_message)
        if data.WhichOneof('branch_message') == 'init_branch':
            lock = threading.Lock()
            lock.acquire()
            balance = data.init_branch.balance
            lock.release()
            branches_add(data.init_branch.all_branches)
            connect_branches()
            sleep(5)
            print("calling sleep thread")
            try:
                th = Thread(target=sleep_thread, args=())
                th.daemon = True
                th.start()
            except KeyboardInterrupt:
                exit()
        if data.WhichOneof('branch_message') == 'transfer':

            if not RECORD[int(data.transfer.src_branch)]:
                lock = threading.Lock()
                lock.acquire()
                balance += data.transfer.money
                print "Balance in the bank after getting transferred money:", balance
                lock.release()
            else:
                print "Recording", data.transfer.src_branch, "->", this_branch, data.transfer.money
                lock = threading.Lock()
                lock.acquire()
                if curr_snap_id not in global_snapshot:
                    global_snapshot[curr_snap_id] = {}
                global_snapshot[curr_snap_id][
                    data.transfer.src_branch] = data.transfer.money
                lock.release()
        if data.WhichOneof('branch_message') == 'init_snapshot':
            print "Received init_snapshot for", this_branch, "with snap_id", data.init_snapshot.snapshot_id
            lock = threading.Lock()
            lock.acquire()
            for obj in RECORD:
                RECORD[obj] = True
            curr_snap_id = data.init_snapshot.snapshot_id
            if curr_snap_id not in global_snapshot:
                global_snapshot[curr_snap_id] = {}
            global_snapshot[curr_snap_id]['balance'] = balance
            lock.release()
            for banks in branch_soc_list:
                marker = bank_pb2.Marker()
                marker.src_branch = str(port)
                marker.dst_branch = str(banks)
                marker.snapshot_id = curr_snap_id
                send_message = bank_pb2.BranchMessage()
                send_message.marker.CopyFrom(marker)
                print "Sending marker to", banks, "for snapshot", curr_snap_id
                branch_soc_list[banks].sendall(
                    send_message.SerializeToString())
        if data.WhichOneof('branch_message') == 'marker':
            if data.marker.snapshot_id != curr_snap_id:
                print "Received marker from", data.marker.src_branch, "and snap_id is", data.marker.snapshot_id
                lock = threading.Lock()
                lock.acquire()
                for obj in RECORD:
                    RECORD[obj] = True
                curr_snap_id = data.marker.snapshot_id
                if curr_snap_id not in global_snapshot:
                    global_snapshot[curr_snap_id] = {}
                global_snapshot[curr_snap_id]['balance'] = balance
                lock.release()
                for banks in branch_soc_list:
                    marker = bank_pb2.Marker()
                    marker.src_branch = str(port)
                    marker.dst_branch = str(banks)
                    marker.snapshot_id = curr_snap_id
                    send_message = bank_pb2.BranchMessage()
                    send_message.marker.CopyFrom(marker)
                    print "Sending marker to", banks, "for snapshot", curr_snap_id
                    branch_soc_list[banks].sendall(
                        send_message.SerializeToString())
                    if banks == data.marker.src_branch:
                        RECORD[banks] = False
            elif marker_count < len(branches_all):
                print "Reply marker from", data.marker.src_branch, "for snapshot", data.marker.snapshot_id
                marker_count += 1
                lock = threading.Lock()
                lock.acquire()
                RECORD[int(data.marker.src_branch)] = False
                if marker_count == len(branches_all):
                    print "Received markers from all. Snapshot created"
                    marker_count = 0
                lock.release()
        if data.WhichOneof('branch_message') == 'retrieve_snapshot':
            print "Received retrieve_snapshot for", this_branch
            snapshot = bank_pb2.ReturnSnapshot()
            snapshot.local_snapshot.snapshot_id = data.retrieve_snapshot.snapshot_id
            for key, val in global_snapshot.items():
                if key == data.retrieve_snapshot.snapshot_id:
                    for key2, val2 in val.items():
                        if key2 != 'balance':
                            snapshot.local_snapshot.channel_state.append(
                                int(str(key2) + str(val2)))
                        else:
                            snapshot.local_snapshot.balance = val2
            send_message = bank_pb2.BranchMessage()
            send_message.return_snapshot.CopyFrom(snapshot)
            client_socket.sendall(send_message.SerializeToString())
                print "Received Amount %s from %s...Total Balance is %s\n" % (
                    str(data.transfer.money), str(
                        client_address[0]), str(BRANCH_BALANCE))

                if MARKER_MSG > 1 or isCapturing:
                    isUpdate = False
            elif data.WhichOneof('branch_message') == 'init_snapshot':
                currentSnapId = data.init_snapshot.snapshot_id
                SNAPSHOTS[currentSnapId] = {}
                SNAPSHOTS[currentSnapId][sys.argv[1]] = BRANCH_BALANCE

                for branch in BRANCH_LIST:
                    SNAPSHOTS[currentSnapId][branch["name"] + "->" +
                                             sys.argv[1]] = []

                marker_msg = bank_pb2.Marker()
                marker_msg.snapshot_id = data.init_snapshot.snapshot_id
                msg = bank_pb2.BranchMessage()
                msg.marker.CopyFrom(marker_msg)

                for branch in BRANCH_LIST:
                    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    s.connect((branch["ip"], branch["port"]))
                    s.sendall(pickle.dumps(msg))
                    s.close()

                isCapturing = True
            elif data.WhichOneof('branch_message') == 'marker':
                if MARKER_MSG == 1:
                    MARKER_MSG = MARKER_MSG + 1
                    if not isCapturing:
Beispiel #9
0
    def handle_marker(cls, incoming_message, remote_branch_name):

        # Temporarily pause the money transfer
        MoneyTransferThread.set_enabled(False)

        # Grab the lock, since the current_snapshots data structure we modify ahead is shared between threads
        cls.marker_handler_lock.acquire()

        snapshot_id = incoming_message.marker.snapshot_id
        if snapshot_id in cls.current_snapshots:
            # This is a reply marker message
            print "Got reply marker msg from: " + str(
                remote_branch_name) + " (snapshot_id: " + str(
                    snapshot_id) + ")"

            # Get the state of the channel on which this marker was received
            total_peers = ThreadPool.get_thread_count()
            for i in range(total_peers):

                a_friend = ThreadPool.get_thread(i)
                if not a_friend:
                    continue

                if a_friend.remote_branch_name == remote_branch_name:
                    # Channel found, get the money recorded on this channel
                    money_in_flight = a_friend.pop_recorder(snapshot_id)

                    # Record the state of the channel
                    cls.current_snapshots[snapshot_id][str(
                        remote_branch_name)] = money_in_flight
                    break

        else:
            # This is the first marker message we're seeing
            print "Got the first marker msg from " + str(remote_branch_name) + " (snapshot_id: "\
                  + str(snapshot_id) + ")"

            # Record local state
            current_balance = BankVault.get_balance()
            state = {"local": current_balance}
            cls.current_snapshots[snapshot_id] = state

            # Record the state of the incoming channel from the sender to itself as empty
            cls.current_snapshots[snapshot_id][str(remote_branch_name)] = 0

            # Create marker message
            marker_msg = bank_pb2.Marker()
            marker_msg.snapshot_id = snapshot_id

            pb_msg = bank_pb2.BranchMessage()
            pb_msg.marker.CopyFrom(marker_msg)

            # Send marker msg to all outgoing channels, except self
            total_peers = ThreadPool.get_thread_count()
            for i in range(total_peers):
                a_friend = ThreadPool.get_thread(i)
                if not a_friend:
                    continue
                '''# MY HACK BEGIN --- ONLY FOR TESTING
                if a_friend.remote_branch_name == remote_branch_name:
                    transfer_msg_h = bank_pb2.Transfer()
                    pb_msg_h = bank_pb2.BranchMessage()

                    transfer_msg_h.money = 10

                    pb_msg_h.transfer.CopyFrom(transfer_msg_h)

                    a_friend.send_msg_to_remote(pb_msg_h)
                # MY HACK END ---'''

                print "Sending marker message to : " + str(a_friend.remote_branch_name) + " (snapshot_id: " \
                      + str(snapshot_id) + ")"
                a_friend.send_msg_to_remote(pb_msg)

                # Start recording all incoming activity
                if a_friend.remote_branch_name != remote_branch_name:
                    a_friend.add_recorder(snapshot_id)

        # Release the lock, we're done modifying the shared data structure
        cls.marker_handler_lock.release()

        # Resume the money transfer thread
        MoneyTransferThread.set_enabled(True)
Beispiel #10
0
def thread_listener(sock, handler):
    init_received = False
    c_ip = ''
    c_port = 0

    # Listen for init message
    while True:
        connection, client = sock.accept()
        try:
            while True:
                data = connection.recv(1024)

                if data:
                    init_received = True
                    msg = bank_pb2.BranchMessage()
                    msg.ParseFromString(data)
                    handler.balance = msg.init_branch.balance 
                    
                    for i in msg.init_branch.all_branches:
                        handler.b_counter = handler.b_counter + 1
                        handler.b_names.append(i.name)
                        handler.b_ips.append(i.ip)
                        handler.b_ports.append(i.port)

                    handler.b_counter = handler.b_counter - 1
                    c_ip = handler.b_ips[handler.b_counter]
                    c_port = handler.b_ports[handler.b_counter]
                    handler.b_names.pop()
                    handler.b_ips.pop()
                    handler.b_ports.pop()
                else:
                    break
        finally:
            connection.close()
        if init_received:
            handler.start_connecting = True
            break

    # Listen for other messages
    while True:
        connection, client = sock.accept()
        try:
            while True:
                data = connection.recv(1024)
                
                if data:
                    msg = bank_pb2.BranchMessage()
                    msg.ParseFromString(data)

                    if msg.HasField('transfer'):
                        money = msg.transfer.money
                        # print handler.name + ' receives ' + str(money) + ' from ' + msg.transfer.branch_name
                        
                        # Update channel during snapshot algorithm 
                        # print '         ' + str(handler.b_recording)
                        # print '         ' + msg.transfer.branch_name

                        if msg.transfer.branch_name in handler.b_recording:
                            # print '     ' + handler.name + ' receives and appends ' + str(money) + ' from ' + msg.transfer.branch_name
                            handler.incoming_names.append(msg.transfer.branch_name)
                            handler.incoming_balances.append(money)
                        else:
                            # print '     ' + handler.name + ' receives ' + str(money) + ' from ' + msg.transfer.branch_name
                            balance_lock.acquire()
                            handler.balance = handler.balance + money
                            balance_lock.release()

                    elif msg.HasField('init_snapshot'):
                        # balance_lock.acquire()
                        handler.markers_going = True
                        # print handler.name + ' Init Snapshot received - local: ' +  str(handler.balance)
                        handler.state_balance = handler.balance
                        handler.current_snapshot_id = msg.init_snapshot.snapshot_id
                        
                        for i in range(0, handler.b_counter):
                            if handler.b_names[i] != handler.name:
                                handler.b_recording.append(handler.b_names[i])
                                addr = (handler.b_ips[i], handler.b_ports[i])
                                
                                try:
                                    m = bank_pb2.Marker()
                                    m.snapshot_id = handler.current_snapshot_id
                                    m.branch_name = handler.name
                                    
                                    msg = bank_pb2.BranchMessage()            
                                    msg.marker.CopyFrom(m)
           
                                    # print handler.name + ' sends marker to ' + handler.b_names[i]
                                    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                                    s.connect(addr)
                                    s.sendall(msg.SerializeToString())
                                except Exception as e:
                                    print handler.name + ' could not send the marker message'
                                    print e
                                s.close()
                        handler.markers_going = False
                        # balance_lock.release()
                    elif msg.HasField('marker'):
                        # print 'marker msg received'
                        # Not first marker message
                        if handler.current_snapshot_id == msg.marker.snapshot_id:
                            # print handler.name + ' Second marker received from ' + msg.marker.branch_name
                            if msg.marker.branch_name in handler.b_recording:
                                handler.b_recording.remove(msg.marker.branch_name)
                        # First marker message
                        else:
                            # balance_lock.acquire()
                            handler.markers_going = True
                            mm = msg.marker.branch_name 
                            # print handler.name + ' First marker received from ' + mm + ' - local: ' + str(handler.balance)
                            handler.current_snapshot_id = msg.marker.snapshot_id
                            handler.state_balance = handler.balance
   
                            # Set marker`s channel to 0 and start recording other channels
                            handler.incoming_names.append(msg.marker.branch_name)
                            handler.incoming_balances.append(0)

                            for i in range(0, handler.b_counter):
                                n = handler.b_names[i]
                                if handler.name != n and mm != n:
                                    #print "         mm: " + mm
                                    #print "         record: " + n
                                    handler.b_recording.append(n)
                                # Send markers
                                if handler.name != n:
                                    addr = (handler.b_ips[i], handler.b_ports[i])        
                                    try:
                                        m = bank_pb2.Marker()
                                        m.snapshot_id = handler.current_snapshot_id
                                        m.branch_name = handler.name

                                        msg = bank_pb2.BranchMessage()            
                                        msg.marker.CopyFrom(m)
                                        
                                        # print handler.name + ' sends marker to ' + handler.b_names[i]
                                        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                                        s.connect(addr)
                                        s.sendall(msg.SerializeToString())
                                    except:
                                        print handler.name + ' could not send the marker message from first'
                                    finally:
                                        s.close()
                            handler.markers_going = False
                            # balance_lock.release()
                    elif msg.HasField('retrieve_snapshot'):
                        # print handler.name + ' Retrieve Snapshot received'

                        if msg.retrieve_snapshot.snapshot_id == handler.current_snapshot_id:
                            # Send return snapshot message
                            r = bank_pb2.ReturnSnapshot()
                            r.local_snapshot.snapshot_id = handler.current_snapshot_id
                            r.local_snapshot.balance = handler.state_balance

                            names = []
                            balances = []

                            for index, i in enumerate(handler.incoming_names):
                                if i not in names:
                                    names.append(i)
                                    balances.append(handler.incoming_balances[index])
                                else:
                                    ind = names.index(i)
                                    balances[ind] = balances[ind] + handler.incoming_balances[index]

                            # Populate channel states
                            for i in balances:
                            # for i in handler.incoming_balances:
                                r.local_snapshot.channel_state.append(i)
                            
                            msg = bank_pb2.BranchMessage()
                            msg.return_snapshot.CopyFrom(r)

                            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                            server_address = (c_ip, c_port)
                            s.connect(server_address)

                            try:
                                # print handler.name + ' Response sent'
                                s.sendall(msg.SerializeToString())
                            except:
                                print 'Could not send response message'
                            finally:
                                s.close()
                        
                            balance_lock.acquire()
                            for i in balances:
                            # for i in handler.incoming_balances:
                                handler.balance = handler.balance + i
                            balance_lock.release()

                            handler.incoming_names = []
                            handler.incoming_balances = []
                            handler.b_recording = []
                        else:
                            print 'Error in retrieve snapshot - ids do not match'
                    else:
                        print 'Incoming data has wrong protobuf format'
                break
        finally:
            connection.close()