def add_block(self, block): # Add the seed block to the known blocks self.blocks[sha256(block)] = block # Store the block in redis r.zadd("miners:" + str(self.id) + ":blocks", block.height, sha256(block)) # Announce block if chain_head isn't empty if self.chain_head == "*": self.chain_head = sha256(block) # If block height is greater than chain head and valid, update chain head and announce new head if (block.height > self.blocks[self.chain_head].height) and block.valid: self.chain_head = sha256(block) self.announce_block(self.chain_head)
def add_block(self, block): # Add the block to the known blocks self.blocks[sha256(block)] = block # Store the block in redis r.zadd("miners:" + str(self.id) + ":blocks", block.height, sha256(block)) # Announce block if chain_head isn't empty if self.chain_head == "*": self.chain_head = sha256(block) # Ignore all blocks that are not mined by the bad miner if block.miner_id != self.id: return # If block height is greater than chain head, update chain head and announce new head if block.height > self.blocks[self.chain_head].height: self.chain_head = sha256(block) self.announce_block(block)
def notify_new_block(self, block): self.total_blocks += 1 if Miner.LOGGING_MODE == "debug": print("height = {}, name = {}, valid = {}, time = {}, hash = {}".format( block.height, self.name, (block.valid == 1), round(self.env.now, 4), sha256(block))) self.block_mined.succeed(block) # Create a new mining event self.block_mined = self.env.event()
def add_block(self, block): # Save block self.blocks[sha256(block)] = block if self.chain_head == "*": self.chain_head = sha256(block) self.chain_head_others = sha256(block) return if (block.miner_id == self.id) and (block.height > self.blocks[self.chain_head].height): delta_prev = self.blocks[self.chain_head].height - self.blocks[self.chain_head_others].height self.chain_head = sha256(block) self.private_branch_len += 1 if (delta_prev == 0) and (self.private_branch_len == 2): self.announce_block(self.chain_head) self.private_branch_len = 0 if (block.miner_id != self.id) and (block.height > self.blocks[self.chain_head_others].height): delta_prev = self.blocks[self.chain_head].height - self.blocks[self.chain_head_others].height self.chain_head_others = sha256(block) if delta_prev <= 0: self.chain_head = sha256(block) self.private_branch_len = 0 elif delta_prev == 1: self.announce_block(self.chain_head) elif delta_prev == 2: self.announce_block(self.chain_head) self.private_branch_len = 0 else: iter_hash = self.chain_head temp = 0 print(delta_prev) if delta_prev >= 6: temp = 1 while self.blocks[iter_hash].height != block.height + temp: iter_hash = self.blocks[iter_hash].prev self.announce_block(iter_hash)
def store(self): key = "events:" + repr(self.id) # Store event data = { "destination": self.destination, "origin": self.origin, "action": self.action, "payload": self.payload, "time": self.time } if isinstance(self.payload, Block): data['payload'] = sha256(self.payload) r.hmset(key, data) day = moment.days_passed(self.time) r.zadd("events", self.time, self.id) r.zadd("days:" + repr(day) + ":events:" + repr(self.action), self.time, self.id) r.zadd("days:" + repr(day) + ":events", self.time, self.id) r.zadd("miners:" + repr(self.origin) + ":events", self.time, self.id)
def add_block(self, block): # Add the seed block to the known blocks self.blocks[sha256(block)] = block # Store the block in redis r.zadd("miners:" + str(self.id) + ":blocks", block.height, sha256(block)) # Announce block if chain_head isn't empty if self.chain_head == "*": self.chain_head = sha256(block) self.chain_head_others = sha256(block) if not block.valid: if block.height > self.blocks[self.chain_head].height: self.chain_head = sha256(block) self.invalid_len += 1 self.announce_block(block) else: if block.height > self.blocks[self.chain_head_others].height: self.chain_head_others = sha256(block) # do we continue the attack or restart the "simulation" if not self.restart: if self.invalid_len > 0: self.honest_len += 1 # if attacker has already forked to invalid chain, we increment the counter # or if the attacker has not forked, we restart on top of the honest network if ((block.height > self.blocks[self.chain_head].height and self.invalid_len == 0) or self.honest_len == self.tgt_cfrms): self.chain_head = sha256(block) if Miner.LOGGING_MODE == "debug": print('att - new chain head = {}, honest_lead = {}'.format(self.chain_head, self.honest_len)) self.announce_block(block) else: self.honest_len += 1 # if the attacker gets the final block for target confirmations here, reset values if self.invalid_len == self.tgt_cfrms or self.honest_len == self.tgt_cfrms: if self.invalid_len == self.tgt_cfrms: self.wins += 1 self.win.succeed() self.win = self.env.event() else: self.loses += 1 self.lose.succeed() self.lose = self.env.event() self.honest_len = 0 self.invalid_len = 0
def announce_block(self, block): if self.id == 8: print("Announce %s - %s" % (block, self.blocks[block].miner_id)) self.broadcast(Miner.HEAD_NEW, sha256(block))
def wait_for_new_block(self): while True: try: # Wait for a block to be mined or received blocks = yield self.block_mined | self.block_received # Interrupt the mining process so the block can be added self.stop_mining() #print("%d \tI stop mining" % self.id) for event, block in blocks.items(): if Miner.LOGGING_MODE == "debug": print("BBB | {} - received block at {}, height - {}, mined by {}, hash - {}, prev = {}".format(self.name, self.env.now, block.height, block.miner_name, sha256(block), block.prev)) # Add the new block to the pending ones self.blocks_new.append(block) # Process new blocks yield self.env.process(self.process_new_blocks()) # Keep mining if self.blocks[self.chain_head].height > 0: if not self.blocks[self.chain_head].validated_yet and self.val_frac > 0: self.env.process(self.validate_chain_head()) self.keep_mining() except simpy.Interrupt as i: # When the mining process is interrupted it cannot continue until it is told to continue yield self.continue_mining
def process_new_blocks(self): blocks_later = [] # Validate every new block for block in self.blocks_new: if Miner.LOGGING_MODE == "debug": print('PPP | {} processing block at height {}, hash - {}, prev - {}'.format(self.name, block.height, sha256(block), block.prev)) # Block validation is skipped for SPV miners yield self.env.timeout(0.0000001) valid = self.verify_block(block) # print(block, valid) if valid == 1: self.add_block(block) elif valid == 0: #Logger.log(self.env.now, self.id, "NEED_DATA", sha256(block)) self.request_block(block.prev) blocks_later.append(block) self.blocks_new = blocks_later