def Event(rate = eventRate): """ Control routine to perform tasks triggered by an event """ # sc.events.your_event_name.createFilter(fromBlock=block, toBlock=block, argument_filters={"arg1": "value"}, topics=[]) blockFilter = w3.eth.filter('latest') def blockHandle(): """ Tasks when a new block is added to the chain """ global ubi, payout, newRound # 1) Log relevant block details block = w3.eth.getBlock(blockHex) blocklog.log([time.time()-block.timestamp, round(block.timestamp-blocklog.tStart, 3), block.number, block.hash.hex(), block.parentHash.hex(), block.difficulty, block.totalDifficulty, block.size, len(block.transactions), len(block.uncles)]) # 2) Log relevant smart contract details balance = getBalance() ubi = sc.functions.askForUBI().call() payout = sc.functions.askForPayout().call() robotCount = sc.functions.getRobotCount().call() mean = sc.functions.getMean().call() voteCount = sc.functions.getVoteCount().call() voteOkCount = sc.functions.getVoteOkCount().call() newRound = sc.functions.isNewRound().call() consensus = sc.functions.isConverged().call() sclog.log([block.number, balance, ubi, payout, robotCount, mean, voteCount, voteOkCount, newRound, consensus]) rgb.flashWhite(0.2) if consensus == 1: rgb.setLED(rgb.all, [rgb.green]*3) rgb.freeze() while True: if not startFlag: print('Stopped Events') break tic = TicToc(rate, 'Event') newBlocks = blockFilter.get_new_entries() if newBlocks: synclog.log([len(newBlocks)]) for blockHex in newBlocks: blockHandle() if ubi != 0: sc.functions.askForUBI().transact() if payout != 0: sc.functions.askForPayout().transact() try: if newRound: sc.functions.updateMean().transact() except: pass tic.toc()
def Vote(rate = voteRate): """ Control routine to broadcast current estimate to the blockchain """ ticketPrice = sc.functions.getTicketPrice().call() def sendVote(): vote = int(estimate*1e7) voteHash = sc.functions.sendVote(vote).transact({'from': me.key,'value': w3.toWei(ticketPrice,'ether')}) voteReceipt = w3.eth.waitForTransactionReceipt(voteHash) return voteReceipt time.sleep(rate) while True: if not startFlag: print('Stopped Voting') break tic = TicToc(rate, 'Vote') while True: try: vote = int(estimate*1e7) voteHash = sc.functions.sendVote(vote).transact({'from': me.key,'value': w3.toWei(ticketPrice,'ether')}) voteReceipt = w3.eth.waitForTransactionReceipt(voteHash) mainlog.log(['Voted: {}; Status: {}'.format(estimate, voteReceipt.status)]) votelog.log([vote]) rgb.flashGreen() break except ValueError: mainlog.log(['Failed Vote (No Balance). Balance: {}'.format(getBalance())]) votelog.log([None]) rgb.flashRed() break except: mainlog.log(['Failed Vote (Unexpected). Trying again. Balance: {}'.format(getBalance())]) # Low frequency logging of chaindata size and cpu usage chainSize = getFolderSize('/home/pi/mygethnode/geth') useCPU = str(round(float(os.popen('''grep 'cpu ' /proc/stat | awk '{usage=($2+$4)*100/($2+$4+$5)} END {print usage }' ''').readline()),2)) extralog.log([chainSize,useCPU]) tic.toc()
def Estimate(rate=estimateRate): """ Control routine to update the local estimate of the robot """ global estimate estimate = 0 totalWhite = 0 totalBlack = 0 while True: if not startFlag: print('Stopped Estimating') break else: tic = TicToc(rate, 'Estimate') # Set counters for grid colors newValues = gs.getAvg() if gs.hasFailed(): gs.stop() time.sleep(1) gs.start() estimatelog.log([None]) elif newValues == None: estimatelog.log([None]) else: for value in newValues: if value > 700: totalWhite += 1 # rw.setLEDs(0b11111111) else: totalBlack += 1 # rw.setLEDs(0b00000000) if isbyz: estimate = 0 else: estimate = (0.5 + totalWhite) / (totalWhite + totalBlack + 1) estimatelog.log([ round(estimate, 3), totalWhite, totalBlack, newValues[0], newValues[1], newValues[2] ]) tic.toc()
def Buffer(rate=bufferRate, ageLimit=ageLimit): """ Control routine for robot-to-robot dynamic peering """ global peerBuffer peerBuffer = [] def globalBuffer(): peerFile = open('pi-pucks.txt', 'r') tcp.unlock() for newId in peerFile: newId = newId.strip() if newId not in getIds(): newPeer = Peer(newId) newPeer.w3 = w3 peerBuffer.append(newPeer) for peer in peerBuffer: if not getIds('geth'): try: peer.enode = tcp.request(newPeer.ip, tcp.port) except: pass peerFile.close() def localBuffer(): # Broadcast own ID to E-RANDB erb.transmit(me.id) # Collect new peer IDs from E-RANDB and TCP for newId in erb.getNew(): tcp.allow(newId) if newId not in getIds(): newPeer = Peer(newId) newPeer.w3 = w3 newPeer.ageLimit = ageLimit peerBuffer.append(newPeer) # mainlog.log(['Added {} to buffer'.format(newPeer.id)]) else: peerBuffer[getIds().index(newId)].reset_age() # Perform Buffering tasks for each peer in the buffer for peer in peerBuffer: # If the peer has died (aged out); Remove from buffer if peer.isdead: mainlog.log( ['Killed {} @ age {:.2f}'.format(peer.id, peer.age)]) peerBuffer.pop(getIds().index(peer.id)) tcp.unallow(peer.id) continue # If the peer connection times out; Kill and remove from buffer elif peer.age > 3: peer.isdead = True peerBuffer.pop(getIds().index(peer.id)) tcp.unallow(peer.id) continue # mainlog.log(['Peer {} connection failed'.format(peer.id)]) # If the peer enode is still unknown; make TCP request elif peer.enode == None: try: peer.enode = tcp.request(peer.ip, tcp.port) rw.setLEDs(0b11111111) mainlog.log(['Received {} enode'.format(peer.id)]) except ValueError: pass # print('Peer Refused Connection') except: pass # print('Peering Failed') if not peerBuffer: rw.setLEDs(0b00000000) if bufferlog.isReady(): gethIds = getIds('geth') bufferIds = getIds('buffer') bufferlog.log([ len(gethIds), len(bufferIds), len(tcp.allowed), ';'.join(bufferIds), ';'.join(gethIds), ';'.join(tcp.allowed) ]) while True: if not startFlag: print('Stopped Buffering') break tic = TicToc(rate, 'Buffer') if globalPeers: globalBuffer() else: localBuffer() tic.toc()