def test_invalid_sign(self): key = default_eccrypto.generate_key(u"curve25519") blk = FakeBlock() blk.sign(key) assert not blk.block_invariants_valid()
def test_invariant_invalid_key(self): """ Test if illegal key blocks are not valid. """ block = FakeBlock() block.public_key = b"definitelynotakey" assert not block.block_invariants_valid()
def test_invariant_invalid_com_seq_num(self): """ Test if illegal key blocks are not valid. """ block = FakeBlock() block.com_seq_num = -1 assert not block.block_invariants_valid()
def test_blocks_by_fdiff_with_holes(self, create_batches, insert_function): # init chain blks = create_batches(num_batches=2, num_blocks=100) com_id = blks[0][0].com_id self.val_dots = [] def chain_dots_tester(chain_id, dots): for dot in dots: self.val_dots.append(dot) self.dbms2.add_observer(com_id, chain_dots_tester) wrap_iterate(insert_function(self.dbms, blks[0][:50])) wrap_iterate(insert_function(self.dbms2, blks[1][:20])) wrap_iterate(insert_function(self.dbms2, blks[1][40:60])) assert len(self.val_dots) == 20 blobs = self.reconcile_round(com_id) assert len(blobs) == 41 for b in blobs: self.dbms2.add_block(b, FakeBlock.unpack(b, blks[0][0].serializer)) assert len(self.val_dots) == 20 blobs2 = self.reconcile_round(com_id) assert len(blobs2) == 8 for b in blobs2: self.dbms2.add_block(b, FakeBlock.unpack(b, blks[0][0].serializer)) assert len(self.val_dots) == 20 blobs2 = self.reconcile_round(com_id) assert len(blobs2) == 1 for b in blobs2: self.dbms2.add_block(b, FakeBlock.unpack(b, blks[0][0].serializer)) assert len(self.val_dots) == 70
def test_invariant_negative_timestamp(self): """ Test if negative sequence number blocks are not valid. """ block = FakeBlock() block.timestamp = -1.0 assert not block.block_invariants_valid()
def test_hash_function(self): """ Check if the hash() function returns the Block hash. """ block = FakeBlock() assert block.__hash__(), block.hash_number
def test_hot_start_db(tmpdir): tmp_val = tmpdir block_store = LMDBLockStore(str(tmp_val)) chain_factory = ChainFactory() dbms = DBManager(chain_factory, block_store) test_block = FakeBlock() packed_block = test_block.pack() dbms.add_block(packed_block, test_block) tx_blob = test_block.transaction assert dbms.get_tx_blob_by_dot(test_block.com_id, test_block.com_dot) == tx_blob assert ( dbms.get_block_blob_by_dot(test_block.com_id, test_block.com_dot) == packed_block ) front = dbms.get_chain(test_block.com_id).frontier dbms.close() block_store2 = LMDBLockStore(str(tmp_val)) chain_factory2 = ChainFactory() dbms2 = DBManager(chain_factory2, block_store2) assert dbms2.get_tx_blob_by_dot(test_block.com_id, test_block.com_dot) == tx_blob assert ( dbms2.get_block_blob_by_dot(test_block.com_id, test_block.com_dot) == packed_block ) assert dbms2.get_chain(test_block.com_id).frontier == front dbms2.close() tmp_val.remove()
def test_sign(self): """ Test signing a block and whether the signature is valid """ crypto = default_eccrypto block = FakeBlock() assert crypto.is_valid_signature(block.key, block.pack(signature=False), block.signature)
async def test_send_receive_raw_block(monkeypatch, mocker, set_vals_by_key): blk = FakeBlock(transaction=b"test") set_vals_by_key.nodes[0].overlay.send_block( blk.pack(), [set_vals_by_key.nodes[1].overlay.my_peer]) monkeypatch.setattr(MockDBManager, "add_block", lambda _, __, ___, prefix: None) monkeypatch.setattr(MockDBManager, "has_block", lambda _, __: False) spy = mocker.spy(MockDBManager, "has_block") await deliver_messages() spy.assert_called_with(ANY, blk.hash)
async def test_send_incorrect_block(monkeypatch, mocker, set_vals_by_key): blk = FakeBlock(transaction=b"test") set_vals_by_key.nodes[0].overlay.send_block( blk.pack(signature=False), [set_vals_by_key.nodes[1].overlay.my_peer]) spy = mocker.spy(PlexusBlock, "unpack") spy2 = mocker.spy(PlexusBlock, "block_invariants_valid") await deliver_messages() spy.assert_called_once() spy2.assert_called_once() assert spy2.spy_return is False
async def test_reject_block(mocker, set_vals_by_key): blk = FakeBlock(com_id=set_vals_by_key.community_id) set_vals_by_key.nodes[0].overlay.reject(blk) spy = mocker.spy(set_vals_by_key.nodes[1].overlay, "validate_persist_block") await deliver_messages() spy.assert_called_with(ANY, set_vals_by_key.nodes[0].overlay.my_peer)
def test_create_next_pers(self, monkeypatch): """ Test creating a block that points towards a previous block """ db = MockDBManager() prev = FakeBlock() monkeypatch.setattr( MockDBManager, "get_chain", lambda _, chain_id: MockChain(), ) monkeypatch.setattr( MockChain, "consistent_terminal", Links((prev.pers_dot, )), ) block = PlexusBlock.create(b"test", encode_raw({b"id": 42}), db, prev.public_key) assert block.previous == Links((prev.pers_dot, )) assert block.sequence_number == prev.sequence_number + 1 assert block.public_key == prev.public_key assert block.signature == EMPTY_SIG assert block.type == b"test" assert block.transaction == encode_raw({b"id": 42}) assert block.com_id == EMPTY_PK assert block.com_seq_num == UNKNOWN_SEQ
async def test_share_in_community(mocker, set_vals_by_key): blk = FakeBlock(com_id=set_vals_by_key.community_id) set_vals_by_key.nodes[0].overlay.share_in_community( blk, set_vals_by_key.community_id) spy = mocker.spy(set_vals_by_key.nodes[1].overlay, "validate_persist_block") await deliver_messages() spy.assert_called_once_with(blk, set_vals_by_key.nodes[0].overlay.my_peer)
def test_get_tx_blob(self): self.test_block = FakeBlock() packed_block = self.test_block.pack() self.dbms.add_block(packed_block, self.test_block) self.tx_blob = self.test_block.transaction assert ( self.dbms.get_tx_blob_by_dot( self.test_block.com_id, self.test_block.com_dot ) == self.tx_blob ) assert ( self.dbms.get_block_blob_by_dot( self.test_block.com_id, self.test_block.com_dot ) == packed_block )
def test_apply_invalid_audit_tx(self, set_vals_by_nodes): blk = FakeBlock(com_id=set_vals_by_nodes.community_id) i = 1 set_vals_by_nodes.nodes[0].overlay.audit_delta = 100 while set_vals_by_nodes.nodes[0].overlay.should_audit_chain_point( blk.com_id, blk.public_key, i): i += 1 tx = (i, {b"t": (True, True)}) with pytest.raises(InvalidAuditTransactionException): set_vals_by_nodes.nodes[0].overlay.apply_audit_tx(blk, tx)
def std_vals(self): self.chain_id = b"chain_id" self.block_dot = Dot((3, ShortKey("808080"))) self.block_dot_encoded = encode_raw(self.block_dot) self.dot_id = self.chain_id + self.block_dot_encoded self.test_hash = b"test_hash" self.tx_blob = b"tx_blob" self.block_blob = b"block_blob" self.test_block = FakeBlock() self.pers = self.test_block.public_key self.com_id = self.test_block.com_id
def test_create_link_to_pers(self, monkeypatch): """ Test creating a linked half block """ key = default_eccrypto.generate_key(u"curve25519") db = MockDBManager() link = FakeBlock() monkeypatch.setattr( MockDBManager, "get_chain", lambda _, chain_id: MockChain() if chain_id == link.public_key else None, ) monkeypatch.setattr( MockChain, "consistent_terminal", Links((link.pers_dot, )), ) block = PlexusBlock.create( b"test", encode_raw({"id": 42}), db, key.pub().key_to_bin(), com_id=link.public_key, ) # include the personal community # Attach to the assert block.links == Links((link.pers_dot, )) assert block.previous == Links((GENESIS_DOT, )) assert block.sequence_number == GENESIS_SEQ assert block.com_seq_num == link.sequence_number + 1 assert block.public_key == key.pub().key_to_bin() assert block.signature == EMPTY_SIG assert block.type == b"test" assert block.transaction == encode_raw({"id": 42}) assert block.com_id == link.public_key
def test_insert_with_merge_block(self, create_batches, insert_function, chain): batches = create_batches(num_batches=2, num_blocks=10) last_blk1 = batches[0][-1] last_blk2 = batches[1][-1] dot1 = (last_blk1.com_seq_num, last_blk1.short_hash) dot2 = (last_blk2.com_seq_num, last_blk2.short_hash) vals = wrap_return(insert_function(chain, batches[0])) assert len(vals) == 10 assert vals[0][0] == 1 and vals[-1][0] == 10 merge_block = FakeBlock(links=Links((dot1, dot2))) chain.add_block(merge_block.links, merge_block.com_seq_num, merge_block.hash) vals = wrap_return(insert_function(chain, batches[1])) assert len(vals) == 11 assert vals[0][0] == 1 and vals[-1][0] == 11 assert len(list(chain.get_dots_by_seq_num(11))) == 1
def test_block_payload(self): blk = FakeBlock() blk_bytes = blk.pack() payload = blk.serializer.unpack_serializable(BlockPayload, blk_bytes) blk2 = PlexusBlock.from_payload(payload[0]) assert blk2 == blk
def test_short_hash(self): block = FakeBlock() assert shorten(block.hash) == block.short_hash
def test_block_valid(self): blk = FakeBlock() assert blk.block_invariants_valid()
def test_pack_unpack(self): blk = FakeBlock() blk_bytes = blk.pack() blk2 = PlexusBlock.unpack(blk_bytes, blk.serializer) assert blk == blk2
class TestIntegrationDBManager: @pytest.fixture(autouse=True) def setUp(self, tmpdir) -> None: tmp_val = tmpdir self.block_store = LMDBLockStore(str(tmp_val)) self.chain_factory = ChainFactory() self.dbms = DBManager(self.chain_factory, self.block_store) yield self.dbms.close() @pytest.fixture(autouse=True) def setUp2(self, tmpdir) -> None: tmp_val = tmpdir self.block_store2 = LMDBLockStore(str(tmp_val)) self.chain_factory2 = ChainFactory() self.dbms2 = DBManager(self.chain_factory2, self.block_store2) yield try: self.dbms2.close() tmp_val.remove() except FileNotFoundError: pass def test_get_tx_blob(self): self.test_block = FakeBlock() packed_block = self.test_block.pack() self.dbms.add_block(packed_block, self.test_block) self.tx_blob = self.test_block.transaction assert ( self.dbms.get_tx_blob_by_dot( self.test_block.com_id, self.test_block.com_dot ) == self.tx_blob ) assert ( self.dbms.get_block_blob_by_dot( self.test_block.com_id, self.test_block.com_dot ) == packed_block ) def test_add_notify_block_one_chain(self, create_batches, insert_function): self.val_dots = [] def chain_dots_tester(chain_id, dots): for dot in dots: assert (len(self.val_dots) == 0 and dot[0] == 1) or dot[ 0 ] == self.val_dots[-1][0] + 1 self.val_dots.append(dot) blks = create_batches(num_batches=1, num_blocks=100) com_id = blks[0][0].com_id self.dbms.add_observer(com_id, chain_dots_tester) wrap_iterate(insert_function(self.dbms, blks[0])) assert len(self.val_dots) == 100 def test_add_notify_block_with_conflicts(self, create_batches, insert_function): self.val_dots = [] def chain_dots_tester(chain_id, dots): for dot in dots: self.val_dots.append(dot) blks = create_batches(num_batches=2, num_blocks=100) com_id = blks[0][0].com_id self.dbms.add_observer(com_id, chain_dots_tester) wrap_iterate(insert_function(self.dbms, blks[0][:20])) wrap_iterate(insert_function(self.dbms, blks[1][:40])) wrap_iterate(insert_function(self.dbms, blks[0][20:60])) wrap_iterate(insert_function(self.dbms, blks[1][40:])) wrap_iterate(insert_function(self.dbms, blks[0][60:])) assert len(self.val_dots) == 200 def test_blocks_by_frontier_diff(self, create_batches, insert_function): # init chain blks = create_batches(num_batches=2, num_blocks=100) com_id = blks[0][0].com_id wrap_iterate(insert_function(self.dbms, blks[0][:50])) wrap_iterate(insert_function(self.dbms2, blks[1][:50])) front = self.dbms.get_chain(com_id).frontier front_diff = self.dbms2.get_chain(com_id).reconcile(front) vals_request = set() blobs = self.dbms.get_block_blobs_by_frontier_diff( com_id, front_diff, vals_request ) assert len(blobs) == 41 def reconcile_round(self, com_id): front = self.dbms.get_chain(com_id).frontier front_diff = self.dbms2.get_chain(com_id).reconcile(front) vals_request = set() blobs = self.dbms.get_block_blobs_by_frontier_diff( com_id, front_diff, vals_request ) return blobs def test_blocks_by_fdiff_with_holes(self, create_batches, insert_function): # init chain blks = create_batches(num_batches=2, num_blocks=100) com_id = blks[0][0].com_id self.val_dots = [] def chain_dots_tester(chain_id, dots): for dot in dots: self.val_dots.append(dot) self.dbms2.add_observer(com_id, chain_dots_tester) wrap_iterate(insert_function(self.dbms, blks[0][:50])) wrap_iterate(insert_function(self.dbms2, blks[1][:20])) wrap_iterate(insert_function(self.dbms2, blks[1][40:60])) assert len(self.val_dots) == 20 blobs = self.reconcile_round(com_id) assert len(blobs) == 41 for b in blobs: self.dbms2.add_block(b, FakeBlock.unpack(b, blks[0][0].serializer)) assert len(self.val_dots) == 20 blobs2 = self.reconcile_round(com_id) assert len(blobs2) == 8 for b in blobs2: self.dbms2.add_block(b, FakeBlock.unpack(b, blks[0][0].serializer)) assert len(self.val_dots) == 20 blobs2 = self.reconcile_round(com_id) assert len(blobs2) == 1 for b in blobs2: self.dbms2.add_block(b, FakeBlock.unpack(b, blks[0][0].serializer)) assert len(self.val_dots) == 70