def _on_command_coin(self, newpacket, info): coins_list = coins_io.read_coins_from_packet(newpacket) if not coins_list: p2p_service.SendFail(newpacket, 'failed to read coins from packet') return True if coins_list[-1] is None: # TODO: partial result, request more coins lg.warn('partial response, more coins were found but not transferred') del coins_list[-1] if len(coins_list) == 1: acoin = coins_list[0] if not coins_io.validate_coin(acoin): p2p_service.SendFail(newpacket, 'coin validation failed') return True if not coins_io.verify_coin(acoin): p2p_service.SendFail(newpacket, 'coin verification failed') return True if coins_db.exist(acoin): self.automat('valid-coins-received', [acoin, ]) else: self.automat('new-coin-mined', acoin) return True valid_coins = [] for acoin in coins_list: if not coins_io.validate_coin(acoin): continue if not coins_io.verify_coin(acoin): continue valid_coins.append(acoin) if len(valid_coins) == len(coins_list): self.automat('valid-coins-received', valid_coins) else: p2p_service.SendFail(newpacket, 'some non-valid coins received') return True
def _on_inbox_packet(self, newpacket, info, status, error_message): if status != 'finished': return False if newpacket.Command == commands.Coin(): coins_list = coins_io.read_coins_from_packet(newpacket) if not coins_list: p2p_service.SendFail(newpacket, 'failed to read coins from packet') return True if len(coins_list) != 1: p2p_service.SendFail(newpacket, 'expected only one coin to be mined') return True coin_json = coins_list[0] if not coins_io.validate_coin(coin_json): lg.warn('coin not valid: %s' % coin_json) p2p_service.SendFail(newpacket, 'coin not valid') return True if not coins_io.verify_signature(coin_json, 'creator'): lg.warn('creator signature is not valid: %s' % coin_json) p2p_service.SendFail(newpacket, 'creator signature is not valid') return True new_coins.append(coin_json) if not new_coins: # p2p_service.SendFail(newpacket, 'did not received any coins to mine') return False for coin in new_coins: self.automat('new-data-received', coin) return True return False
def _on_results_collected(self, accountant_results): """ """ fails = {} unique_coins = {} for success, result_tuple in accountant_results: accountant_idurl, response_packet = result_tuple if not success: fails[accountant_idurl] = fails.get(accountant_idurl, 0) + 1 continue if response_packet is None: fails[accountant_idurl] = fails.get(accountant_idurl, 0) + 1 continue coins_list = coins_io.read_coins_from_packet(response_packet) if not coins_list: fails[accountant_idurl] = fails.get(accountant_idurl, 0) + 1 continue for coin in coins_list: coin_hash = coin['miner']['hash'] if coin_hash not in unique_coins: unique_coins[coin_hash] = coin if coins_io.coin_to_string(unique_coins[coin_hash] ) != coins_io.coin_to_string(coin): fails[accountant_idurl] = fails.get(accountant_idurl, 0) + 1 if not unique_coins: if _Debug: lg.out( _DebugLevel, 'contract_chain_node._on_results_collected : NO COINS FOUND' ) self.result.callback([]) self._close() return None if fails: lg.warn('conflicting results from accountants: %s' % fails) # TODO: find some simple way to establish consensus between accountants # if one accountant is cheating or failing, coins from his machine must be filtered out # probably here we can trigger a process to replace bad accountants self.result.errback(Exception(str(fails))) self._close() return None if _Debug: lg.out( _DebugLevel, 'contract_chain_node._on_results_collected : %d COINS FOUND' % len(unique_coins)) self.result.callback(unique_coins.values()) return None
def _on_inbox_packet(self, newpacket, info, status, error_message): if status != "finished": return False if newpacket.Command == commands.Coin(): coins_list = coins_io.read_coins_from_packet(newpacket) if not coins_list: # p2p_service.SendFail(newpacket, 'failed to read coins from packet') return False new_coins = [] for acoin in coins_list: if not coins_io.verify_coin_signature(acoin): lg.warn("signature verification failed") continue if coins_io.validate_coin(acoin): continue new_coins.append(acoin) if not new_coins: # p2p_service.SendFail(newpacket, 'did not received any coins to mine') return False for coin in new_coins: self.automat("new-data-received", coin) return True return False