def test_join_quorum_updates_with_block_if_nbn_has_block(self): m = Masternode(wallet=mnw1, ctx=self.ctx, socket_base='ipc:///tmp/n1', bootnodes=bootnodes, constitution=constitution, webserver_port=8080, overwrite=True) block = random_txs.random_block() m.nbn_inbox.q.append(block.to_dict()) k = block.subBlocks[0].transactions[0].state[0].key v = block.subBlocks[0].transactions[0].state[0].value self.assertIsNone(m.client.raw_driver.get_direct(k)) async def add_tx_queue(): await asyncio.sleep(0.3) m.tx_batcher.queue.append(b'blah') m.nbn_inbox.q.append(block.to_dict()) tasks = asyncio.gather(m.join_quorum(), add_tx_queue()) self.loop.run_until_complete(tasks) self.assertEqual(m.client.raw_driver.get_direct(k), v)
def test_random_subblock_converts_successfully(self): sb = random_txs.random_block().subBlocks[0].to_dict() expected_order = ['inputHash', 'merkleLeaves', 'merkleRoot', 'signatures', 'subBlockNum', 'transactions'] sorted_sb = canonical.format_dictionary(sb) sorted_sb_keys = list(sorted_sb.keys()) for i in range(len(sorted_sb_keys)): self.assertEqual(sorted_sb_keys[i], expected_order[i])
def test_add_rewards(self): block = random_txs.random_block() total = 0 for sb in block.subBlocks: for tx in sb.transactions: total += tx.stampsUsed self.assertEqual(self.r.stamps_in_block(block), total)
def test_random_subblock_all_transactions_convert_successfully(self): sb = random_txs.random_block().subBlocks[0].to_dict() expected_order = ['contractName', 'functionName', 'kwargs', 'nonce', 'processor', 'sender', 'stampsSupplied'] sb = canonical.format_dictionary(sb) for tx in sb['transactions']: sorted_tx_keys = list(tx['transaction']['payload'].keys()) self.assertEqual(sorted_tx_keys, expected_order)
def test_random_subblock_all_transactiondata_convert_successfully(self): sb = random_txs.random_block().subBlocks[0].to_dict() sb = canonical.format_dictionary(sb) expected_order = ['stampsUsed', 'state', 'status', 'transaction'] for tx in sb['transactions']: sorted_tx_keys = list(tx.keys()) self.assertEqual(sorted_tx_keys, expected_order)
def test_did_sign_block_false_if_missing_any_merkle_roots(self): b = Delegate(socket_base='tcp://127.0.0.1', wallet=Wallet(), ctx=self.ctx, bootnodes=bootnodes, constitution=constitution) block = random_block() # Add one root but not the other b.pending_sbcs.add(block.subBlocks[0].merkleRoot) self.assertFalse(b.did_sign_block(block))
def test_get_block_blob_by_block_data_request(self): block = random_txs.random_block() w = Wallet() c = CilantroStorageDriver(key=w.sk.encode().hex()) c.drop_collections() d = canonical.block_from_subblocks([s for s in block.subBlocks], previous_hash=b'x/00' * 32, block_num=0) d['blockOwners'] = [secrets.token_bytes(32) for _ in range(12)] c.put(d) del d['_id'] del d['blockOwners'] m = BlockServer(w, 'tcp://127.0.0.1', self.ctx, linger=500, poll_timeout=500, driver=c) async def get(msg): socket = self.ctx.socket(zmq.DEALER) socket.connect('tcp://127.0.0.1:10004') await socket.send(msg) res = await socket.recv() return res message = Message.get_signed_message_packed_2( wallet=w, msg_type=MessageType.BLOCK_DATA_REQUEST, blockNum=0) tasks = asyncio.gather( m.serve(), get(message), stop_server(m, 0.2), ) loop = asyncio.get_event_loop() res = loop.run_until_complete(tasks) msg_type, msg, sender, timestamp, is_verified = Message.unpack_message_2( res[1]) dd = canonical.block_from_subblocks([s for s in msg.subBlocks], previous_hash=b'x/00' * 32, block_num=0) self.assertDictEqual(d, dd)
def test_block_from_subblocks_verify_works(self): sbs = random_txs.random_block().subBlocks block = canonical.block_from_subblocks(subblocks=sbs, previous_hash=b'\x00' * 32, block_num=0) prev_hash = block['prevBlockHash'] prop_hash = block['hash'] valid = canonical.verify_block(sbs, prev_hash, prop_hash) self.assertTrue(valid)
def test_random_subblocks_all_convert_successfully_at_top_level(self): expected_order = ['inputHash', 'merkleLeaves', 'merkleRoot', 'signatures', 'subBlockNum', 'transactions'] block = random_txs.random_block() sbs = [block.subBlocks[i].to_dict() for i in range(len(block.subBlocks))] for sb in sbs: sorted_sb = canonical.format_dictionary(sb) sorted_sb_keys = list(sorted_sb.keys()) for i in range(len(sorted_sb_keys)): self.assertEqual(sorted_sb_keys[i], expected_order[i])
def test_process_nbn_updates_state_with_block_if_did_not_sign_block(self): b = Delegate(socket_base='tcp://127.0.0.1', wallet=Wallet(), ctx=self.ctx, bootnodes=bootnodes, constitution=constitution) block = random_block() k = block.subBlocks[0].transactions[0].state[0].key v = block.subBlocks[0].transactions[0].state[0].value self.assertIsNone(b.client.raw_driver.get_direct(k)) b.process_new_block(block) self.assertEqual(b.client.raw_driver.get_direct(k), v)
def test_update_nonces_with_block(self): block = random_txs.random_block(txs=20) self.db.update_nonces_with_block(block) nonces = self.db.iter(NONCE_KEY) self.assertEqual(len(nonces), 20) vals = [] for n in nonces: vals.append(self.db.get(n)) self.assertEqual(sorted(vals), list(range(1, 21)))
def test_add_pending_rewards(self): block = random_txs.random_block() total = 0 for tx in block.subBlocks[0].transactions: total += tx.stampsUsed expected = ContractingDecimal(total / 100_000) self.assertEqual(self.r.get_pending_rewards(), 0) self.r.add_pending_rewards(block.subBlocks[0]) self.assertEqual(self.r.get_pending_rewards(), expected)
def store_blocks(self, c, i, initial_hash=(b'\x00' * 32).hex()): current_hash = initial_hash for _i in range(i): block = random_txs.random_block(block_num=_i) d = canonical.block_from_subblocks([s for s in block.subBlocks], previous_hash=current_hash, block_num=_i) d['blockOwners'] = [secrets.token_bytes(32) for _ in range(12)] c.put(d) del d['_id'] del d['blockOwners'] current_hash = d['hash']
def test_process_nbn_commits_changes_if_did_sign_block(self): b = Delegate(socket_base='tcp://127.0.0.1', wallet=Wallet(), ctx=self.ctx, bootnodes=bootnodes, constitution=constitution) block = random_block() # Add one root but not the other b.pending_sbcs.add(block.subBlocks[0].merkleRoot) b.pending_sbcs.add(block.subBlocks[1].merkleRoot) b.client.raw_driver.set('A', 'B') self.assertIsNone(b.client.raw_driver.get_direct('A')) b.process_new_block(block) self.assertEqual(b.client.raw_driver.get(b'A'), 'B')
def test_fetch_block_from_multiple_masters_where_some_are_corrupted(self): w = Wallet() c = CilantroStorageDriver(key=w.sk.encode()) c.drop_collections() # Store 20 blocks self.store_blocks(c, 1) # Good one w1 = Wallet() n1 = '/tmp/n1' make_ipc(n1) m1 = BlockServer(socket_base=f'ipc://{n1}', wallet=w1, ctx=self.ctx, linger=500, poll_timeout=500, driver=FakeTopBlockManager(101, 'abcd'), blocks=c) # Bad Ones bad_block = canonical.block_from_subblocks( [s for s in random_txs.random_block().subBlocks], previous_hash=b'\x01' * 32, block_num=0) bad_block['blockOwners'] = [secrets.token_bytes(32) for _ in range(30)] d = FakeBlockDriver(bad_block) w2 = Wallet() n2 = '/tmp/n2' make_ipc(n2) m2 = BlockServer(socket_base=f'ipc://{n2}', wallet=w2, ctx=self.ctx, linger=500, poll_timeout=100, driver=FakeTopBlockManager(101, 'abcd'), blocks=d) w3 = Wallet() n3 = '/tmp/n3' make_ipc(n3) m3 = BlockServer(socket_base=f'ipc://{n3}', wallet=w3, ctx=self.ctx, linger=500, poll_timeout=100, driver=FakeTopBlockManager(101, 'abcd'), blocks=d) class FakeParameters: async def refresh(self): await asyncio.sleep(0.1) def get_masternode_sockets(self, *args): return [ f'ipc://{n1}/blocks', f'ipc://{n2}/blocks', f'ipc://{n3}/blocks', ] f = BlockFetcher(wallet=Wallet(), ctx=self.ctx, parameters=FakeParameters()) tasks = asyncio.gather( m1.serve(), m2.serve(), m3.serve(), f.find_valid_block(0, latest_hash=b'\x00' * 32, timeout=3000), stop_server(m1, 2), stop_server(m2, 2), stop_server(m3, 2), ) loop = asyncio.get_event_loop() res = loop.run_until_complete(tasks) block_dict = c.get_block(0) del block_dict['blockOwners'] got_block = res[3] got = canonical.block_from_subblocks([s for s in got_block.subBlocks], previous_hash=b'\x00' * 32, block_num=0) self.assertDictEqual(block_dict, got)