def setUp(self): p2p_factory = Mock(spec=P2PFactory) p2p_factory.sync_state = SyncState() p2p_factory.num_connections = 23 p2p_factory.pow = Mock() b = Block() self.chain_manager = Mock(spec=ChainManager) self.chain_manager.height = 0 self.chain_manager.get_last_block = MagicMock(return_value=b) self.chain_manager.get_block_header_hash_by_number = MagicMock( return_value=b.headerhash) self.qrlnode = QRLNode(mining_address=b'') self.qrlnode.set_chain_manager(self.chain_manager) self.qrlnode._p2pfactory = p2p_factory self.qrlnode._pow = p2p_factory.pow self.block_header_params = { "dev_config": config.dev, "blocknumber": 10, "prev_headerhash": sha256(b'prevblock'), "prev_timestamp": 1234567890, "hashedtransactions": sha256(b'tx1'), "fee_reward": 1, "seed_height": 0, "seed_hash": None, } self.service = MiningAPIService(self.qrlnode)
def test_GetBlockMiningCompatible(self): p2p_factory = Mock(spec=P2PFactory) p2p_factory.sync_state = SyncState() p2p_factory.num_connections = 23 p2p_factory.pow = Mock() chain_manager = Mock(spec=ChainManager) chain_manager.height = 0 chain_manager.get_last_block = MagicMock(return_value=Block()) qrlnode = QRLNode(mining_address=b'') qrlnode.set_chain_manager(chain_manager) qrlnode._p2pfactory = p2p_factory qrlnode._pow = p2p_factory.pow block_header = BlockHeader.create(blocknumber=10, prev_headerhash=sha256(b'prevblock'), prev_timestamp=1234567890, hashedtransactions=sha256(b'tx1'), fee_reward=1) qrlnode.get_blockheader_and_metadata = MagicMock( return_value=[block_header, BlockMetadata()]) service = MiningAPIService(qrlnode) req = qrlmining_pb2.GetBlockMiningCompatibleReq(height=10) answer = service.GetBlockMiningCompatible(request=req, context=None) self.assertEqual(10, answer.blockheader.block_number) self.assertEqual(1, answer.blockheader.reward_fee)
def start_services(node: QRLNode): public_server = grpc.server( ThreadPoolExecutor(max_workers=1), maximum_concurrent_rpcs=config.user.max_peers_limit) add_BaseServicer_to_server(BaseService(node), public_server) add_PublicAPIServicer_to_server(PublicAPIService(node), public_server) public_server.add_insecure_port("[::]:9009") public_server.start() logger.info("grpc public service - started !") admin_server = grpc.server( ThreadPoolExecutor(max_workers=1), maximum_concurrent_rpcs=config.user.max_peers_limit) add_AdminAPIServicer_to_server(AdminAPIService(node), admin_server) admin_server.add_insecure_port("127.0.0.1:9008") admin_server.start() mining_server = grpc.server( ThreadPoolExecutor(max_workers=1), maximum_concurrent_rpcs=config.user.max_peers_limit) add_MiningAPIServicer_to_server(MiningAPIService(node), mining_server) mining_server.add_insecure_port("[::]:9007") mining_server.start() logger.info("grpc admin service - started !") return admin_server, public_server, mining_server
def start_services(node: QRLNode): public_server = grpc.server( ThreadPoolExecutor(max_workers=config.user.public_api_threads), maximum_concurrent_rpcs=config.user.public_api_max_concurrent_rpc) add_BaseServicer_to_server(BaseService(node), public_server) add_PublicAPIServicer_to_server(PublicAPIService(node), public_server) if config.user.public_api_enabled: public_server.add_insecure_port("{0}:{1}".format( config.user.public_api_host, config.user.public_api_port)) public_server.start() logger.info("grpc public service - started !") admin_server = grpc.server( ThreadPoolExecutor(max_workers=config.user.admin_api_threads), maximum_concurrent_rpcs=config.user.admin_api_max_concurrent_rpc) add_AdminAPIServicer_to_server(AdminAPIService(node), admin_server) if config.user.admin_api_enabled: admin_server.add_insecure_port("{0}:{1}".format( config.user.admin_api_host, config.user.admin_api_port)) admin_server.start() logger.info("grpc admin service - started !") mining_server = grpc.server( ThreadPoolExecutor(max_workers=config.user.mining_api_threads), maximum_concurrent_rpcs=config.user.mining_api_max_concurrent_rpc) add_MiningAPIServicer_to_server(MiningAPIService(node), mining_server) if config.user.mining_api_enabled: mining_server.add_insecure_port("{0}:{1}".format( config.user.mining_api_host, config.user.mining_api_port)) mining_server.start() logger.info("grpc mining service - started !") debug_server = grpc.server( ThreadPoolExecutor(max_workers=config.user.debug_api_threads), maximum_concurrent_rpcs=config.user.debug_api_max_concurrent_rpc) add_DebugAPIServicer_to_server(DebugAPIService(node), debug_server) if config.user.debug_api_enabled: debug_server.add_insecure_port("{0}:{1}".format( config.user.debug_api_host, config.user.debug_api_port)) debug_server.start() logger.info("grpc debug service - started !") return admin_server, public_server, mining_server, debug_server
class TestMiningAPI(TestCase): def setUp(self): p2p_factory = Mock(spec=P2PFactory) p2p_factory.sync_state = SyncState() p2p_factory.num_connections = 23 p2p_factory.pow = Mock() b = Block() self.chain_manager = Mock(spec=ChainManager) self.chain_manager.height = 0 self.chain_manager.get_last_block = MagicMock(return_value=b) self.chain_manager.get_block_header_hash_by_number = MagicMock( return_value=b.headerhash) self.qrlnode = QRLNode(mining_address=b'') self.qrlnode.set_chain_manager(self.chain_manager) self.qrlnode._p2pfactory = p2p_factory self.qrlnode._pow = p2p_factory.pow self.block_header_params = { "dev_config": config.dev, "blocknumber": 10, "prev_headerhash": sha256(b'prevblock'), "prev_timestamp": 1234567890, "hashedtransactions": sha256(b'tx1'), "fee_reward": 1, "seed_height": 0, "seed_hash": None, } self.service = MiningAPIService(self.qrlnode) def test_GetBlockMiningCompatible(self): block_header = BlockHeader.create(**self.block_header_params) self.qrlnode.get_blockheader_and_metadata = MagicMock( return_value=[block_header, BlockMetadata()]) req = qrlmining_pb2.GetBlockMiningCompatibleReq(height=10) answer = self.service.GetBlockMiningCompatible(request=req, context=None) self.assertEqual(10, answer.blockheader.block_number) self.assertEqual(1, answer.blockheader.reward_fee) # if QRLNode responds with None, None, the GRPC response should be blank too self.qrlnode.get_blockheader_and_metadata = MagicMock( return_value=[None, None]) answer = self.service.GetBlockMiningCompatible(request=req, context=None) self.assertEqual(0, answer.blockheader.block_number) self.assertEqual(0, answer.blockheader.reward_fee) def test_GetLastBlockHeader(self): self.block_header_params["blocknumber"] = 20 block_header = BlockHeader.create(**self.block_header_params) self.chain_manager.height = 200 self.qrlnode.get_blockheader_and_metadata = MagicMock( return_value=[block_header, BlockMetadata()]) req = qrlmining_pb2.GetLastBlockHeaderReq(height=20) answer = self.service.GetLastBlockHeader(request=req, context=None) self.assertEqual(180, answer.depth) self.assertEqual(200, answer.height) def test_GetBlockToMine(self): blocktemplate_blob = b'blob' difficulty = 100 self.qrlnode.get_block_to_mine = MagicMock( return_value=(blocktemplate_blob, difficulty)) req = qrlmining_pb2.GetBlockToMineReq(wallet_address=b'fake address') answer = self.service.GetBlockToMine(request=req, context=None) self.assertEqual(answer.height, 1) self.assertEqual(answer.reserved_offset, config.dev.extra_nonce_offset) # What happens if QRLNode could not generate a blocktemplate? Then the response should be blank. self.qrlnode.get_block_to_mine.return_value = None answer = self.service.GetBlockToMine(request=req, context=None) self.assertEqual('', answer.blocktemplate_blob) self.assertEqual(0, answer.height) self.assertEqual(0, answer.reserved_offset) self.assertEqual(0, answer.difficulty) def test_SubmitMinedBlock(self): req = qrlmining_pb2.SubmitMinedBlockReq(blob=b'minedblob') # Submit mined block encountered an error self.qrlnode.submit_mined_block = MagicMock(return_value=False) answer = self.service.SubmitMinedBlock(req, context=None) self.assertTrue(answer.error) # This time it was successful self.qrlnode.submit_mined_block = MagicMock(return_value=True) answer = self.service.SubmitMinedBlock(req, context=None) self.assertFalse(answer.error)