def recvAndSet(sock, i): global mesSlot, recvConds, ballot, myVal, procNo, acceptNum, acceptVal, states global activeFailed, linkSuc global queue global acceptBallot global acceptSlot, acceptCond global promiseSlot, promiseCond global myBlock, tempBlock global leader global balance global decideCond while True: le = safeRec(sock, 2) le = unpack(">H", le)[0] mes = safeRec(sock, le) newone = paxos_pb2.Prepare() newone.ParseFromString(mes) # getting Prepare, set the ballot number if greater and return promise if newone.type == 1: if (newone.ballot.num > ballot.num or (newone.ballot.num == ballot.num and newone.ballot.pid >= procNo)) and newone.ballot.depth >= len(ballot.blockChain): ballot.num = newone.ballot.num leader = False if newone.ballot.depth > ballot.depth: sendForRecovery(ballot.depth, newone.ballot.depth) ballot.depth = newone.ballot.depth returned = paxos_pb2.Promise() returned.type = 3 returned.ballot.CopyFrom(newone.ballot) returned.acceptNum.CopyFrom(acceptNum) returned.acceptVal.CopyFrom(acceptVal) threading.Thread(target=waitSend, args=( sock, returned, )).start() elif newone.type == 3: if len(promiseSlot) <= 2: newone = paxos_pb2.Promise() newone.ParseFromString(mes) promiseSlot.append((i, newone)) if len(promiseSlot) == 2: promiseCond.acquire() promiseCond.notifyAll() promiseCond.clear() promiseCond.release() # promiseSlot to be cleared elif newone.type == 4: newone = paxos_pb2.Accept() newone.ParseFromString(mes) if (newone.myVal.num > ballot.num or (newone.myVal.num == ballot.num and newone.myVal.pid > ballot.pid)) and newone.myVal.depth >= len(states.blockChain): leader = False insi = newone.myVal.trans states.queue.append((i, insi)) then = paxos_pb2.Accepted() then.type = 5 acceptNum = newone.ballot acceptVal = newone.myVal then.ballot.CopyFrom(newone.ballot) then.acceptVal.CopyFrom(newone.myVal) threading.Thread(target=waitSend, args=( sock, then, )).start() continue elif newone.type == 5: if len(acceptSlot) < 2: newone = paxos_pb2.Accepted() newone.ParseFromString(mes) if newone.ballot == acceptBallot: acceptSlot.append(newone) elif len(acceptSlot) == 2: acceptCond.acquire() acceptCond.notifyAll() acceptSlot.clear() acceptCond.release() # acceptSlot to be cleared elif newone.type == 6: newone = paxos_pb2.Decide() newone.ParseFromString(mes) if newone.val not in states.blockChain: states.blockChain.append(newone.val) for ite in newone.val.trans: if ite.rcvr == procNo: states.balance += ite.amt ballot.depth = len(states.blockChain) # clearQueue(i) tempBlock = paxos_pb2.Block() decideCond.acquire() decideCond.notifyAll() decideCond.release() elif newone.type == 7: newone = paxos_pb2.Recover() newone.ParseFromString(mes) if newone.depth < ballot.depth: then = paxos_pb2.RepRecover() then.type = 8 then.depth = newone.depth then.block.CopyFrom(states.blockChain[depth]) waitSend(sock, then) elif newone.type == 8: newone = paxos_pb2.RepRecover() newone.ParseFromString(mes) addToBlockChain(newone) continue
def recvAndSet(sock, i): global recvConds, ballot, myVal, procNo, acceptNum, acceptVal, states global activeFailed, linkSuc global acceptBallot global acceptSlot, acceptCond global promiseSlot, promiseCond global myBlock, tempBlock global decideCond global acceptingPromise global acceptingAcced global promiseSlotLock global blockChainLock global acceptSlotLock while True: le = safeRec(sock, 2) if le == b'': socks[i] = -1 linkSuc[i - 1] = False return le = unpack(">H", le)[0] mes = safeRec(sock, le) newone = paxos_pb2.Prepare() newone.ParseFromString(mes) # getting Prepare, set the ballot number if greater and return promise if activeFailed[i - 1] == True: continue if newone.type == 1: print("Prepared") # print(newone.ballot) # print(ballot) if newone.ballot.depth > len(states.blockChain): ask = paxos_pb2.Recover() ask.type = 7 threading.Thread(target=waitSend, args=( sock, ask, )).start() if newone.ballot.depth > ballot.depth or ( newone.ballot.depth == ballot.depth and newone.ballot.num > ballot.num) or (newone.ballot.depth == ballot.depth and newone.ballot.num == ballot.num and newone.ballot.pid >= ballot.pid): ballot.CopyFrom(newone.ballot) #if newone.ballot.depth > ballot.depth: # sendForRecovery(ballot.depth, newone.ballot.depth) # ballot.depth = newone.ballot.depth returned = paxos_pb2.Promise() returned.type = 3 returned.ballot.CopyFrom(newone.ballot) returned.acceptNum.CopyFrom(acceptNum) returned.acceptVal.CopyFrom(acceptVal) print("Sending") threading.Thread(target=waitSend, args=( sock, returned, )).start() elif newone.type == 3: print("Promised") newone = paxos_pb2.Promise() newone.ParseFromString(mes) promiseSlotLock.acquire() if newone.ballot == ballot and acceptingPromise: print("Still in phase") print("Length: ", len(promiseSlot)) if len(promiseSlot) < 2: # print("Going on") promiseSlot.append((i, newone)) if len(promiseSlot) == 2: # print("Here") promiseCond.acquire() promiseCond.notifyAll() acceptingPromise = False # promiseSlot.clear() promiseCond.release() promiseSlotLock.release() # else: # print("Debug: promiseSlot not equal 2 ", promiseSlot) # else: # print("Debug: promiseSlot ", promiseSlot) # else: # print("Promised, newone.ballot ", newone.ballot) # print("Promised, ballot ", ballot) # # promiseSlot to be cleared, not here elif newone.type == 4: print("Got accept from " + str(i)) newone = paxos_pb2.Accept() newone.ParseFromString(mes) if newone.ballot.depth > len(states.blockChain): ask = paxos_pb2.Recover() ask.type = 7 threading.Thread(target=waitSend, args=( sock, ask, )).start() if newone.ballot.depth > ballot.depth or ( newone.ballot.depth == ballot.depth and newone.ballot.num > ballot.num) or (newone.ballot.depth == ballot.depth and newone.ballot.num == ballot.num and newone.ballot.pid >= ballot.pid): print("Sending back accepted") then = paxos_pb2.Accepted() then.type = 5 acceptNum.CopyFrom(newone.ballot) acceptVal.CopyFrom(newone.myVal) then.ballot.CopyFrom(newone.ballot) then.acceptVal.CopyFrom(newone.myVal) threading.Thread(target=waitSend, args=( sock, then, )).start() else: print("Did not accept") print("newone.ballot ", newone.ballot) print("local ballot: ", ballot) elif newone.type == 5: print("Accepted from " + str(i)) newone = paxos_pb2.Accepted() newone.ParseFromString(mes) acceptSlotLock.acquire() if len(acceptSlot) < 2 and acceptingAcced: if newone.ballot == acceptBallot: acceptSlot.append(newone) if len(acceptSlot) == 2: acceptCond.acquire() acceptCond.notifyAll() acceptingAcced = False acceptSlot.clear() acceptCond.release() acceptSlotLock.release() # acceptSlot to be cleared elif newone.type == 6: newone = paxos_pb2.Decide() newone.ParseFromString(mes) if newone.ballot.depth > len(states.blockChain): ask = paxos_pb2.Recover() ask.type = 7 threading.Thread(target=waitSend, args=( sock, ask, )).start() if newone.val not in states.blockChain: blockChainLock.acquire() states.blockChain.append(newone.val) blockChainLock.release() for ite in newone.val.trans: if ite.rcvr == procNo: states.balance += ite.amt ballot.depth = len(states.blockChain) if newone.val == myBlock: print("cleaning myBLock") myBlock = paxos_pb2.Block() if newone.val == tempBlock: print("cleaning tempBlock and acceptVal") tempBlock = paxos_pb2.Block() if newone.val == acceptVal: print("cleaning acceptVal") acceptVal = paxos_pb2.Block() else: print("Error: ") print(newone.val) print(acceptVal) decideCond.acquire() decideCond.notifyAll() decideCond.release() elif newone.type == 7: zaWarudo = states.blockChain.copy() returned = paxos_pb2.RepRecover() returned.type = 8 returned.insi.extend(zaWarudo) threading.Thread(target=waitSend, args=( sock, returned, )).start() # newone = paxos_pb2.Recover() # newone.ParseFromString(mes) # if newone.depth < ballot.depth: # then = paxos_pb2.RepRecover() # then.type = 8 # then.depth = newone.depth # then.block.CopyFrom(states.blockChain[depth]) # waitSend(sock, then) elif newone.type == 8: thend = paxos_pb2.RepRecover() thend.ParseFromString(mes) # print("Type 8: ", thend) threading.Thread(target=recovery, args=(thend, )).start()