def test_sync_state_change_synced(self): chain_manager = Mock() chain_manager.height = 0 chain_manager.get_block = MagicMock(return_value=GenesisBlock()) chain_manager.last_block = GenesisBlock() chain_manager.tx_pool = Mock() chain_manager.tx_pool.transaction_pool = [] get_block_metadata_response = Mock() get_block_metadata_response.block_difficulty = StringToUInt256('2') chain_manager.state.get_block_metadata = MagicMock(return_value=get_block_metadata_response) alice_xmss = get_alice_xmss() chain_manager.state.get_address = MagicMock(return_value=AddressState.get_default(alice_xmss.address)) chain_manager.state.get_measurement = MagicMock(return_value=60) p2p_factory = Mock() sync_state = Mock() time_provider = Mock() node = POW(chain_manager=chain_manager, p2p_factory=p2p_factory, sync_state=sync_state, time_provider=time_provider, slaves=get_random_master(), mining_thread_count=0) self.assertIsNotNone(node) node.update_node_state(ESyncState.synced)
def test_sync_state_change_synced(self): chain_manager = Mock() chain_manager.height = 0 chain_manager.get_block = MagicMock(return_value=GenesisBlock()) chain_manager.last_block = GenesisBlock() chain_manager.tx_pool = Mock() chain_manager.tx_pool.transaction_pool = [] chain_manager.tx_pool.transactions = chain_manager.tx_pool.transaction_pool get_block_metadata_response = Mock() get_block_metadata_response.block_difficulty = StringToUInt256('2') chain_manager.state.get_block_metadata = MagicMock( return_value=get_block_metadata_response) alice_xmss = get_alice_xmss() chain_manager.state.get_address = MagicMock( return_value=AddressState.get_default(alice_xmss.address)) chain_manager.state.get_measurement = MagicMock(return_value=60) p2p_factory = Mock() sync_state = Mock() time_provider = Mock() # Setting mining enabled False, when update_note_state set to synced, # starts miner which is not exited properly by unit test with set_mining_enabled(False): node = POW(chain_manager=chain_manager, p2p_factory=p2p_factory, sync_state=sync_state, time_provider=time_provider, mining_credit_wallet=get_random_xmss().address, mining_thread_count=0) self.assertIsNotNone(node) node.update_node_state(ESyncState.synced)
def test_load(self): with set_data_dir('no_data'): with State() as state: genesis_block = GenesisBlock() chain_manager = ChainManager(state) chain_manager.load(genesis_block) block = state.get_block(GenesisBlock().headerhash) self.assertIsNotNone(block)
def pre_pos_2(self, data=None): logger.info('pre_pos_2') if self.chain.height() >= 1: return # assign hash terminators to addresses and generate a temporary stake list ordered by st.hash.. tmp_list = [] for tx in self.chain.transaction_pool: if tx.subtype == qrl.core.Transaction_subtypes.TX_SUBTYPE_STAKE: if tx.txfrom in self.chain.m_blockchain[0].stake_list and tx.first_hash: tmp_list.append([tx.txfrom, tx.hash, 0, tx.first_hash, GenesisBlock().get_info()[tx.txfrom], tx.slave_public_key]) self.chain.state.stake_validators_list.add_sv(tx.txfrom, tx.slave_public_key, tx.hash, tx.first_hash, GenesisBlock().get_info()[tx.txfrom]) self.chain.block_chain_buffer.epoch_seed = self.chain.state.calc_seed(tmp_list) self.chain.stake_list = sorted(tmp_list, key=lambda staker: self.chain.score(stake_address=staker[0], reveal_one=bin2hstr(sha256(reduce(lambda set1, set2: set1 + set2, staker[1]))), balance=staker[4], seed=self.chain.block_chain_buffer.epoch_seed)) self.chain.block_chain_buffer.epoch_seed = format(self.chain.block_chain_buffer.epoch_seed, 'x') logger.info('genesis stakers ready = %s / %s', len(self.chain.stake_list), config.dev.minimum_required_stakers) logger.info('node address: %s', self.chain.mining_address) if len(self.chain.stake_list) < config.dev.minimum_required_stakers: # stake pool still not full..reloop.. self.p2pFactory.send_st_to_peers(data) logger.info('waiting for stakers.. retry in 5s') reactor.callID = reactor.callLater(5, self.pre_pos_2, data) return if self.chain.mining_address == self.chain.stake_list[0][0]: logger.info('designated to create block 1: building block..') tmphc = hashchain(self.chain.wallet.address_bundle[0].xmss.get_seed_private()) # create the genesis block 2 here.. reveal_hash, vote_hash = self.chain.select_hashchain(self.chain.m_blockchain[-1].blockheader.headerhash, self.chain.mining_address, tmphc.hashchain, blocknumber=1) b = self.chain.m_create_block(reveal_hash[-2], vote_hash[-2]) self.pre_block_logic(b) else: logger.info('await block creation by stake validator: %s', self.chain.stake_list[0][0]) self.last_bk_time = time.time() self.restart_unsynced_logic() return
def load(self, genesis_block): height = self.state.get_mainchain_height() if height == -1: self.state.put_block(genesis_block, None) block_number_mapping = qrl_pb2.BlockNumberMapping(headerhash=genesis_block.headerhash, prev_headerhash=genesis_block.prev_headerhash) self.state.put_block_number_mapping(genesis_block.block_number, block_number_mapping, None) parent_difficulty = StringToUInt256(str(config.dev.genesis_difficulty)) self.current_difficulty, _ = DifficultyTracker.get( measurement=config.dev.mining_setpoint_blocktime, parent_difficulty=parent_difficulty) block_metadata = BlockMetadata.create() block_metadata.set_orphan(False) block_metadata.set_block_difficulty(self.current_difficulty) block_metadata.set_cumulative_difficulty(self.current_difficulty) self.state.put_block_metadata(genesis_block.headerhash, block_metadata, None) addresses_state = dict() for genesis_balance in GenesisBlock().genesis_balance: bytes_addr = genesis_balance.address addresses_state[bytes_addr] = AddressState.get_default(bytes_addr) addresses_state[bytes_addr]._data.balance = genesis_balance.balance self.state.state_objects.update_current_state(addresses_state) self.state.state_objects.push(genesis_block.headerhash) else: self.last_block = self.get_block_by_number(height) self.current_difficulty = self.state.get_block_metadata(self.last_block.headerhash).block_difficulty
def test_destroy_current_state(self): with set_data_dir('no_data'): with State() as state: genesis_block = GenesisBlock() state.put_block(genesis_block, None) dummy_state = StateLoader( bin2hstr(genesis_block.headerhash).encode(), state._db) state.state_objects.append_state_loader(dummy_state) alice_xmss = get_alice_xmss() alice_address_state = AddressState.get_default( alice_xmss.address) for _ in range(10): alice_address_state.increase_nonce() addresses_state = {alice_xmss.address: alice_address_state} state.state_objects.update_current_state(addresses_state) alice_address_state2 = state.get_address(alice_xmss.address) self.assertEqual(alice_address_state.nonce, alice_address_state2.nonce) state.state_objects.destroy_current_state(None) alice_address_state2 = state.get_address(alice_xmss.address) self.assertEqual(0, alice_address_state2.nonce)
def test_genesis_block_values(self): gb = GenesisBlock() self.assertIsNotNone(gb) self.assertEqual(0, gb.block_number) self.assertEqual(b'QuantumBoosterTestnet', gb.prev_headerhash) self.assertEqual(6, len(gb.genesis_balance))
def __init__(self, state): self.state = state self.tx_pool = TransactionPool() # TODO: Move to some pool manager self.last_block = Block.from_json(GenesisBlock().to_json()) self.current_difficulty = StringToUInt256(str(config.dev.genesis_difficulty)) self.trigger_miner = False
def create(num_blocks): start_time = time.time() with mock.patch('qrl.core.misc.ntp.getTime') as ntp_mock, \ set_data_dir('no_data'), \ State() as state, \ mock.patch('time.time') as time_mock: # noqa time_mock.return_value = start_time ntp_mock.return_value = start_time state.get_measurement = MagicMock(return_value=10000000) genesis_difficulty = config.dev.genesis_difficulty try: config.dev.genesis_difficulty = 10 genesis_block = GenesisBlock() chain_manager = ChainManager(state) chain_manager.load(genesis_block) chain_manager._difficulty_tracker = Mock() dt = DifficultyTracker() tmp_difficulty = StringToUInt256('2') tmp_target = dt.get_target(tmp_difficulty) chain_manager._difficulty_tracker.get = MagicMock(return_value=(tmp_difficulty, tmp_target)) qrlnode = QRLNode(state, mining_credit_wallet=b'') qrlnode.set_chain_manager(chain_manager) mock_blockchain = MockedBlockchain(qrlnode, time_mock, ntp_mock, ) for block_idx in range(1, num_blocks + 1): mock_blockchain.add_new_block() yield mock_blockchain finally: config.dev.genesis_difficulty = genesis_difficulty
def qrlnode_with_mock_blockchain(num_blocks): start_time = time.time() with mock.patch('qrl.core.misc.ntp.getTime') as ntp_mock, \ set_data_dir('no_data'), \ State() as state, \ mock.patch('time.time') as time_mock: # noqa time_mock.return_value = start_time ntp_mock.return_value = start_time state.get_measurement = MagicMock(return_value=10000000) required_height = ceil(log(num_blocks, 2)) required_height = int(required_height + required_height % 2) alice_xmss = get_alice_xmss(xmss_height=required_height) bob_xmss = get_bob_xmss() genesis_block = GenesisBlock() chain_manager = ChainManager(state) chain_manager.load(genesis_block) chain_manager._difficulty_tracker = Mock() dt = DifficultyTracker() tmp_difficulty = StringToUInt256('2') tmp_target = dt.get_target(tmp_difficulty) chain_manager._difficulty_tracker.get = MagicMock(return_value=(tmp_difficulty, tmp_target)) block_prev = state.get_block(genesis_block.headerhash) for block_idx in range(1, num_blocks): transactions = [] if block_idx == 1: slave_tx = SlaveTransaction.create(slave_pks=[bob_xmss.pk], access_types=[0], fee=0, xmss_pk=alice_xmss.pk) slave_tx.sign(alice_xmss) slave_tx._data.nonce = 2 transactions = [slave_tx] time_mock.return_value = time_mock.return_value + 60 ntp_mock.return_value = ntp_mock.return_value + 60 block_new = Block.create(block_number=block_idx, prevblock_headerhash=block_prev.headerhash, transactions=transactions, miner_address=alice_xmss.address) while not PoWValidator().validate_mining_nonce(state, block_new.blockheader, False): block_new.set_nonces(block_new.mining_nonce + 1, 0) chain_manager.add_block(block_new) block_prev = block_new qrlnode = QRLNode(state, mining_credit_wallet=alice_xmss.address) qrlnode.set_chain_manager(chain_manager) yield qrlnode
def main(): args = parse_arguments() logger.debug( "=====================================================================================" ) logger.info("QRL Path: %s", args.qrl_dir) config.user.qrl_dir = expanduser(args.qrl_dir) config.create_path(config.user.qrl_dir) logger.debug( "=====================================================================================" ) config.create_path(config.user.wallet_dir) mining_address = None if config.user.mining_enabled: mining_address = get_mining_address(args.mining_address) if not mining_address: logger.warning('Invalid Mining Credit Wallet Address') logger.warning('%s', args.mining_address) return False ntp.setDrift() if args.debug: logger.warning("FAULT HANDLER ENABLED") faulthandler.enable() logger.info('Initializing chain..') persistent_state = State() if args.measurement > -1: persistent_state.get_measurement = MagicMock( return_value=args.measurement) chain_manager = ChainManager(state=persistent_state) chain_manager.load(Block.from_json(GenesisBlock().to_json())) qrlnode = QRLNode(db_state=persistent_state, mining_address=mining_address) qrlnode.set_chain_manager(chain_manager) set_logger(args, qrlnode.sync_state) ####### # NOTE: Keep assigned to a variable or might get collected admin_service, grpc_service, mining_service = start_services(qrlnode) qrlnode.start_listening() qrlnode.connect_peers() qrlnode.start_pow(args.mining_thread_count) logger.info('QRL blockchain ledger %s', config.dev.version) logger.info('mining/staking address %s', args.mining_address) # FIXME: This will be removed once we move away from Twisted reactor.run()
def gen_blocks(block_count, state, miner_address): blocks = [] block = None with mock.patch('qrl.core.misc.ntp.getTime') as time_mock: time_mock.return_value = 1615270948 addresses_state = dict() for i in range(0, block_count): if i == 0: block = GenesisBlock() for genesis_balance in GenesisBlock().genesis_balance: bytes_addr = genesis_balance.address addresses_state[bytes_addr] = AddressState.get_default( bytes_addr) addresses_state[ bytes_addr]._data.balance = genesis_balance.balance else: block = Block.create(block_number=i, prev_headerhash=block.headerhash, prev_timestamp=block.timestamp, transactions=[], miner_address=miner_address) addresses_set = state.prepare_address_list(block) for address in addresses_set: addresses_state[address] = state.get_address_state(address) for tx_protobuf in block.transactions: tx = Transaction.from_pbdata(tx_protobuf) tx.apply_state_changes(addresses_state) block.set_nonces(10, 0) blocks.append(block) metadata = BlockMetadata() metadata.set_block_difficulty(StringToUInt256('256')) state.put_block_metadata(block.headerhash, metadata, None) state.put_block(block, None) bm = qrl_pb2.BlockNumberMapping( headerhash=block.headerhash, prev_headerhash=block.prev_headerhash) state.put_block_number_mapping(block.block_number, bm, None) state.update_mainchain_height(block.block_number, None) state.put_addresses_state(addresses_state) return blocks
def __init__(self, state): self._state = state self.tx_pool = TransactionPool(None) self._last_block = Block.deserialize(GenesisBlock().serialize()) self.current_difficulty = StringToUInt256( str(config.user.genesis_difficulty)) self.trigger_miner = False self.lock = threading.RLock()
def test_genesis_block_values(self): with clean_genesis(): gb = GenesisBlock() self.assertIsNotNone(gb) self.assertEqual(0, gb.block_number) self.assertEqual(config.user.genesis_prev_headerhash, gb.prev_headerhash) self.assertEqual(1, len(gb.genesis_balance))
def setUp(self): self.state = Mock(autospec=State) self.state.get_measurement.return_value = 10000000 del GenesisBlock.instance # Removing Singleton instance self.genesis_block = GenesisBlock() self.chain_manager = ChainManager(self.state) self.chain_manager.tx_pool = Mock() self.chain_manager._difficulty_tracker = Mock()
def setUp(self): with set_qrl_dir('no_data'): self.state = State() self.state.get_measurement = Mock(return_value=10000000) del GenesisBlock.instance # Removing Singleton instance self.genesis_block = GenesisBlock() self.chain_manager = ChainManager(self.state) self.chain_manager._difficulty_tracker = Mock()
def test_load(self): # load() has the following tasks: # Write Genesis Block into State immediately # Register block_number <-> blockhash mapping # Calculate difficulty Metadata for Genesis Block # Generate AddressStates from Genesis Block balances # Apply Genesis Block's transactions to the state self.chain_manager.load(self.genesis_block) block = self.state.get_block(GenesisBlock().headerhash) self.assertIsNotNone(block)
def load(self, genesis_block): height = self.state.get_mainchain_height() if height == -1: self.state.put_block(genesis_block, None) block_number_mapping = qrl_pb2.BlockNumberMapping(headerhash=genesis_block.headerhash, prev_headerhash=genesis_block.prev_headerhash) self.state.put_block_number_mapping(genesis_block.block_number, block_number_mapping, None) parent_difficulty = StringToUInt256(str(config.dev.genesis_difficulty)) self.current_difficulty, _ = DifficultyTracker.get( measurement=config.dev.mining_setpoint_blocktime, parent_difficulty=parent_difficulty) block_metadata = BlockMetadata.create() block_metadata.set_orphan(False) block_metadata.set_block_difficulty(self.current_difficulty) block_metadata.set_cumulative_difficulty(self.current_difficulty) self.state.put_block_metadata(genesis_block.headerhash, block_metadata, None) addresses_state = dict() for genesis_balance in GenesisBlock().genesis_balance: bytes_addr = genesis_balance.address addresses_state[bytes_addr] = AddressState.get_default(bytes_addr) addresses_state[bytes_addr]._data.balance = genesis_balance.balance for tx_idx in range(1, len(genesis_block.transactions)): tx = Transaction.from_pbdata(genesis_block.transactions[tx_idx]) for addr in tx.addrs_to: addresses_state[addr] = AddressState.get_default(addr) coinbase_tx = Transaction.from_pbdata(genesis_block.transactions[0]) if not isinstance(coinbase_tx, CoinBase): return False addresses_state[coinbase_tx.addr_to] = AddressState.get_default(coinbase_tx.addr_to) if not coinbase_tx.validate_extended(): return False coinbase_tx.apply_on_state(addresses_state) for tx_idx in range(1, len(genesis_block.transactions)): tx = Transaction.from_pbdata(genesis_block.transactions[tx_idx]) tx.apply_on_state(addresses_state) self.state.state_objects.update_current_state(addresses_state) self.state.state_objects.update_tx_metadata(genesis_block, None) self.state.state_objects.push(genesis_block.headerhash) else: self.last_block = self.get_block_by_number(height) self.current_difficulty = self.state.get_block_metadata(self.last_block.headerhash).block_difficulty
def get_state(self, header_hash: bytes, addresses_set: set): tmp_header_hash = header_hash parent_headerhash = None addresses_state = dict() for address in addresses_set: addresses_state[address] = None while True: if self.state_objects.contains(header_hash): parent_headerhash = header_hash self.set_addresses_state(addresses_state, header_hash) break block = self.get_block(header_hash) if not block: logger.warning('[get_state] No Block Found %s', header_hash) break if block.block_number == 0: break header_hash = block.prev_headerhash for genesis_balance in GenesisBlock().genesis_balance: bytes_addr = genesis_balance.address if not addresses_state[bytes_addr]: addresses_state[bytes_addr] = AddressState.get_default( bytes_addr) addresses_state[ bytes_addr]._data.balance = genesis_balance.balance for address in addresses_state: if not addresses_state[address]: addresses_state[address] = AddressState.get_default(address) header_hash = tmp_header_hash hash_path = [] while True: if parent_headerhash == header_hash: break block = self.get_block(header_hash) if not block: break hash_path.append(header_hash) header_hash = block.prev_headerhash if block.block_number == 0: break for header_hash in hash_path[-1::-1]: block = self.get_block(header_hash) for tx_pbdata in block.transactions: tx = Transaction.from_pbdata(tx_pbdata) tx.apply_on_state(addresses_state) return addresses_state
def prepare_address_list(block) -> set: addresses = set() for proto_tx in block.transactions: tx = Transaction.from_pbdata(proto_tx) tx.set_effected_address(addresses) for genesis_balance in GenesisBlock().genesis_balance: bytes_addr = genesis_balance.address if bytes_addr not in addresses: addresses.add(bytes_addr) return addresses
def f_read_chain(self, epoch): delimiter = config.dev.binary_file_delimiter block_list = [] if not os.path.isfile(self.get_chaindatafile(epoch)): if epoch != 0: return [] logger.info('Creating new chain file') genesis_block = GenesisBlock().set_chain(self) block_list.append(genesis_block) return block_list try: with open(self.get_chaindatafile(epoch), 'rb') as myfile: jsonBlock = bytearray() tmp = bytearray() count = 0 offset = 0 while True: chars = myfile.read(config.dev.chain_read_buffer_size) for char in chars: offset += 1 if count > 0 and char != delimiter[count]: count = 0 jsonBlock += tmp tmp = bytearray() if char == delimiter[count]: tmp.append(delimiter[count]) count += 1 if count < len(delimiter): continue tmp = bytearray() count = 0 pos = offset - len(delimiter) - len(jsonBlock) jsonBlock = bz2.decompress(jsonBlock) block = Block.from_json(jsonBlock) self.update_block_metadata(block.blockheader.blocknumber, pos, len(jsonBlock)) block_list.append(block) jsonBlock = bytearray() continue jsonBlock.append(char) if len(chars) < config.dev.chain_read_buffer_size: break except Exception as e: logger.error('IO error %s', e) return [] return block_list
def get_genesis_with_only_coin_base_txn(coin_base_reward_addr, dev_config): g = GenesisBlock() coin_base_tx = Transaction.from_pbdata(g.transactions[0]) coin_base_tx.update_mining_address(coin_base_reward_addr) # Remove all other transaction except CoinBase txn del g.transactions[:] g.pbdata.transactions.extend([coin_base_tx.pbdata]) g.blockheader.generate_headerhash(dev_config) return g
def test_sync_state_change_synced(self): buffered_chain = Mock() buffered_chain.height = 0 buffered_chain.get_block = MagicMock(return_value=GenesisBlock()) p2p_factory = Mock() sync_state = Mock() time_provider = Mock() node = POS(buffered_chain=buffered_chain, p2p_factory=p2p_factory, sync_state=sync_state, time_provider=time_provider) self.assertIsNotNone(node) node.update_node_state(ESyncState.synced)
def main(): args = parse_arguments() config.create_path(config.user.wallet_dir) mining_credit_wallet = get_mining_credit_wallet(args.mining_credit_wallet) if not mining_credit_wallet: logger.warning('Invalid Mining Credit Wallet Address') logger.warning('%s', args.mining_credit_wallet) return False logger.debug( "=====================================================================================" ) logger.info("Data Path: %s", args.data_dir) config.user.data_dir = args.data_dir config.create_path(config.user.data_dir) ntp.setDrift() logger.info('Initializing chain..') persistent_state = State() chain_manager = ChainManager(state=persistent_state) chain_manager.load(Block.from_json(GenesisBlock().to_json())) qrlnode = QRLNode(db_state=persistent_state, mining_credit_wallet=mining_credit_wallet) qrlnode.set_chain_manager(chain_manager) set_logger(args, qrlnode.sync_state) ####### # NOTE: Keep assigned to a variable or might get collected admin_service, grpc_service, mining_service = start_services(qrlnode) qrlnode.start_listening() qrlnode.connect_peers() qrlnode.start_pow(args.mining_thread_count) logger.info('QRL blockchain ledger %s', config.dev.version) logger.info('mining/staking address %s', args.mining_credit_wallet) # FIXME: This will be removed once we move away from Twisted reactor.run()
def test_add_genesis(self): with State() as state: with set_wallet_dir("test_wallet"): chain = Mock(spec=Chain) chain.height = 0 chain.get_block = MagicMock(return_value=None) chain.wallet = Wallet() chain.pstate = state buffered_chain = BufferedChain(chain) b0 = buffered_chain.get_block(0) buffered_chain._chain.get_block.assert_called() self.assertIsNone(b0) res = buffered_chain.add_block(block=GenesisBlock()) self.assertTrue(res)
def clean_genesis(): data_name = "no_data" dst_dir = tempfile.mkdtemp() prev_val = config.user.qrl_dir try: GenesisBlock.instance = None test_path = os.path.dirname(os.path.abspath(__file__)) src_dir = os.path.join(test_path, "..", "data", data_name) shutil.rmtree(dst_dir) shutil.copytree(src_dir, dst_dir) config.user.qrl_dir = dst_dir _ = GenesisBlock() # noqa config.user.qrl_dir = prev_val yield finally: shutil.rmtree(dst_dir) GenesisBlock.instance = None config.user.qrl_dir = prev_val
def test_getStats(self): db_state = Mock(spec=State) db_state.total_coin_supply = MagicMock(return_value=1000) db_state.get_measurement = MagicMock(return_value=60) p2p_factory = Mock(spec=P2PFactory) p2p_factory.sync_state = SyncState() p2p_factory.connections = 23 p2p_factory.pow = Mock() chain_manager = Mock(spec=ChainManager) chain_manager.height = 0 chain_manager.get_last_block = MagicMock(return_value=GenesisBlock()) chain_manager.get_block_by_number = MagicMock(return_value=None) chain_manager.state = db_state qrlnode = QRLNode(db_state, mining_address=b'') qrlnode.set_chain_manager(chain_manager) qrlnode._p2pfactory = p2p_factory qrlnode._pow = p2p_factory.pow service = PublicAPIService(qrlnode) request = qrl_pb2.GetStatsReq() stats = service.GetStats(request=request, context=None) # self.assertEqual(__version__, stats.node_info.version) # FIXME self.assertEqual(qrl_pb2.NodeInfo.UNSYNCED, stats.node_info.state) self.assertEqual(23, stats.node_info.num_connections) # self.assertEqual("testnet", stats.node_info.network_id) # FIXME self.assertEqual(0, stats.epoch) self.assertEqual(0, stats.uptime_network) self.assertEqual(65000000000000000, stats.block_last_reward) self.assertEqual(60, stats.block_time_mean) self.assertEqual(0, stats.block_time_sd) self.assertEqual(105000000, stats.coins_total_supply) self.assertEqual(1000, stats.coins_emitted) self.assertEqual(0, len(stats.block_timeseries))
def test_simple_add_block(self): with set_data_dir('no_data'): with State() as state: state.get_measurement = MagicMock(return_value=10000000) alice_xmss = get_alice_xmss() genesis_block = GenesisBlock() chain_manager = ChainManager(state) chain_manager.load(genesis_block) chain_manager._difficulty_tracker = Mock() dt = DifficultyTracker() tmp_difficulty = StringToUInt256('2') tmp_target = dt.get_target(tmp_difficulty) chain_manager._difficulty_tracker.get = MagicMock( return_value=(tmp_difficulty, tmp_target)) block = state.get_block(genesis_block.headerhash) self.assertIsNotNone(block) with mock.patch('qrl.core.misc.ntp.getTime') as time_mock: time_mock.return_value = 1615270948 # Very high to get an easy difficulty block_1 = Block.create( block_number=1, prevblock_headerhash=genesis_block.headerhash, transactions=[], miner_address=alice_xmss.address) block_1.set_nonces(491, 0) from pyqrllib.pyqrllib import bin2hstr print(bin2hstr(block.headerhash)) # Uncomment only to determine the correct mining_nonce of above blocks # from qrl.core.PoWValidator import PoWValidator # while not PoWValidator().validate_mining_nonce(state, block_1.blockheader, False): # block_1.set_nonces(block_1.mining_nonce + 1) # print(block_1.mining_nonce) result = chain_manager.add_block(block_1) self.assertTrue(result) self.assertEqual(chain_manager.last_block, block_1)
def test_simple_add_block(self): with set_data_dir('no_data'): with State() as state: state.get_measurement = MagicMock(return_value=10000000) alice_xmss = get_alice_xmss() genesis_block = GenesisBlock() chain_manager = ChainManager(state) chain_manager.load(genesis_block) chain_manager._difficulty_tracker = Mock() dt = DifficultyTracker() tmp_difficulty = StringToUInt256('2') tmp_boundary = dt.get_target(tmp_difficulty) chain_manager._difficulty_tracker.get = MagicMock( return_value=(tmp_difficulty, tmp_boundary)) block = state.get_block(genesis_block.headerhash) self.assertIsNotNone(block) with mock.patch('qrl.core.misc.ntp.getTime') as time_mock: time_mock.return_value = 1615270948 # Very high to get an easy difficulty block_1 = Block.create( block_number=1, prevblock_headerhash=genesis_block.headerhash, transactions=[], signing_xmss=alice_xmss, master_address=alice_xmss.address, nonce=1) while not PoWValidator().validate_mining_nonce( state, block_1.blockheader, False): block_1.set_mining_nonce(block_1.mining_nonce + 1) result = chain_manager.add_block(block_1) self.assertTrue(result) self.assertEqual(chain_manager.last_block, block_1)
def main(): persistent_state = State() chain_manager = ChainManager(state=persistent_state) chain_manager.load(GenesisBlock()) ph = PoWHelper() difficulty = StringToUInt256('5000') filename = os.path.expanduser( "~/crypto/qryptonight/modeling/blockdata.csv") with open(filename, 'w') as f: f.write("i,timestamp,prev_timestamp,delta,difficulty,target\n") prev_timestamp = None for i in range(chain_manager.height): block = chain_manager.get_block_by_number(i) if i == 0: prev_timestamp = block.blockheader.timestamp continue target = ph.getTarget(difficulty) delta = block.blockheader.timestamp - prev_timestamp outs = "{},{},{},{},{},{}\n".format(i, block.blockheader.timestamp, prev_timestamp, delta, UInt256ToString(difficulty), UInt256ToString(target)) f.write(outs) difficulty = ph.getDifficulty(block.blockheader.timestamp, prev_timestamp, difficulty) difficulty = StringToUInt256( str(max(2, int(UInt256ToString(difficulty))))) prev_timestamp = block.blockheader.timestamp