def oneRound(): global states, procNo global myBlock global acceptVal, acceptNum # global proposed global tempBlock global started global decideCond global blockChainLock started = True while len(states.queue) > 0 or myBlock != paxos_pb2.Block( ) or tempBlock != paxos_pb2.Block(): time.sleep(randomVal()) ballot.num += 1 ballot.pid = procNo ballot.depth = len(states.blockChain) res = ElectAsLeader() if res == True: print("Starting as leader") res = transPrepare() if res == True: print("Second phase") if tempBlock == paxos_pb2.Block(): sendDecide() if myBlock not in states.blockChain: blockChainLock.acquire() states.blockChain.append(myBlock) blockChainLock.release() for ite in myBlock.trans: states.balance -= ite.amt myBlock = paxos_pb2.Block() ballot.depth = len(states.blockChain) else: print("Waiting for decision 0") print("Tempblock: ", tempBlock) decideCond.acquire() decideCond.wait(7) decideCond.release() else: # Wait on decision to be made print("Waiting on decision 1") decideCond.acquire() decideCond.wait(14) decideCond.release() # print("Accepting phase failed or not original value") else: # Wait on decision to be made print("Waiting on decision 2") decideCond.acquire() decideCond.wait(21) decideCond.release() # print("Failed to become leader") started = False
def oneRound(): global states, procNo global myBlock global acceptVal, acceptNum # global proposed global tempBlock global started global leader global balance global decideCond started = True while leader: time.sleep(randomVal()) res = ElectAsLeader() if res == True and leader == True: res = transPrepare() if res == True: if tempBlock == paxos_pb2.Block(): sendDecide() if myBlock not in states.blockChain: states.blockChain.append(myBlock) balance -= myBlock.amt acceptVal = paxos_pb2.Block() acceptNum = paxos_pb2.BallotNum() myBlock = paxos_pb2.Block() started = False return True else: acceptVal = paxos_pb2.Block() acceptNum = paxos_pb2.BallotNum() tempBlock = paxos_pb2.Block() leader = True else: # Wait on decision to be made print("Waiting on decision") decideCond.acquire() decideCond.wait() decideCond.release() leader = True # print("Accepting phase failed or not original value") else: # Wait on decision to be made print("Waiting on decision") decideCond.acquire() decideCond.wait() decideCond.release() leader = True
def sendAccept(sock, i): global ballot, states global acceptBallot global procNo global myBlock global tempBlock newone = paxos_pb2.Accept() newone.type = 4 newone.ballot.CopyFrom(ballot) if tempBlock == paxos_pb2.Block(): qualified = [ite[1] for ite in states.queue if ite[0] == procNo] # qualified = [] # for ite in states.queue: # if ite[0] == procNo: # qualified.append(ite[1]) newone.myVal.trans.extend(qualified) if len(states.blockChain) == 0: newone.myVal.hash = hashlib.sha256('').hexdigest() else: newone.myVal.hash = hashlib.sha256(states.blockChain[-1].SerializeToString()).hexdigest() setNonce(newone.myVal) states.queue.clear() myBlock.CopyFrom(newone.myVal) else: newone.myVal.CopyFrom(tempBlock) # states.blockChain[-1].hash acceptBallot.CopyFrom(newone.ballot) waitSend(sock, newone)
def sendDecide(): global procNo global ballot global tempBlock global myBlock global acceptBallot de = paxos_pb2.Decide() de.type = 6 de.src = procNo de.ballot.CopyFrom(acceptBallot) if tempBlock != paxos_pb2.Block(): de.val.CopyFrom(tempBlock) else: de.val.CopyFrom(myBlock) for ite in socks: if linkSuc[ite - 1] == True: threading.Thread(target = waitSend, args = (socks[ite], de,)).start()
def ElectAsLeader(): global procNo, promiseCount, activeFailed, responded global tempBlock global promiseSlot global states global acceptingPromise responded.append(procNo) quq = [] acceptingPromise = True for i in [1, 2, 3, 4, 5]: if i != procNo and activeFailed[i - 1] == False: t = threading.Thread(target=askForPromise, args=(i, )) t.start() quq.append(t) for ite in quq: ite.join() promiseCond.acquire() res = promiseCond.wait(6) promiseCond.release() # if promiseCount < 3: if res == False: print("Returning False") return False tempBlock = maxOf(promiseSlot) if tempBlock != paxos_pb2.Block(): print("promoseSlot with temp", promiseSlot, tempBlock) print("Length before cleared ", len(promiseSlot)) promiseSlot.clear() print("Length after cleared ", len(promiseSlot)) return True
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
states = State() if path.isfile("State_" + str(procNo)): with open("State_" + str(procNo)) as f: states = pickle.load(f) # In[48]: # print("This is stub") # tes = hashlib.sha256("nihao".encode("utf-8")).hexdigest() # print(findNonce(tes)) ports = {1: 10001, 2: 10002, 3: 10003, 4: 10004, 5: 10005} socks = {} sockLocks = {} responded = [] myVal = paxos_pb2.Block() acceptVals = [] promiseCount = 1 PCLock = threading.Lock() countLock = threading.Lock() # failed = False # enough = threading.Condition() ballot = paxos_pb2.BallotNum() ballot.num = states.ballot.num ballot.pid = procNo ballot.depth = len(states.blockChain) acceptBallot = paxos_pb2.BallotNum() acceptCount = 0
def transPrepare(): global procNo, responded, states, socks global linkSuc global acceptCond global acceptingAcced # toSent = paxos_pb2.Block() # toSent.trans.extend(states.queue) # if len(states.blockChain) == 0: # toSent.hash = "" # else: # toSent.hash = newone = paxos_pb2.Accept() newone.type = 4 newone.ballot.CopyFrom(ballot) if tempBlock != paxos_pb2.Block(): newone.myVal.CopyFrom(tempBlock) elif myBlock != paxos_pb2.Block(): newone.myVal.CopyFrom(myBlock) else: acceptBallot.CopyFrom(newone.ballot) newone.myVal.trans.extend(states.queue.copy()) # print("newone.myVal.trans: ", newone.myVal.trans) # print("states.queue: " , states.queue.copy()) if len(states.blockChain) == 0: newone.myVal.hash = hashlib.sha256(b'').hexdigest() else: newone.myVal.hash = hashlib.sha256( states.blockChain[-1].SerializeToString()).hexdigest() setNonce(newone.myVal) states.queue.clear() myBlock.CopyFrom(newone.myVal) print("myblock: ", myBlock) acceptingAcced = True quq = [] for ite in socks: if ite != procNo and linkSuc[ite - 1] == True and activeFailed[ite - 1] == False: t = threading.Thread(target=waitSend, args=( socks[ite], newone, )) quq.append(t) t.start() for ite in quq: ite.join() acceptCond.acquire() res = acceptCond.wait(7) acceptCond.release() return res
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()