Пример #1
0
 def test_validate_not_sane_zeroes(self):
     db = self.MockDatabase()
     block1 = MultiChainBlock()
     # Act
     block1.up = 0
     block1.down = 0
     result = block1.validate(db)
     self.assertEqual(result[0], ValidationResult.invalid)
     self.assertIn("Up and down are zero", result[1])
Пример #2
0
 def test_validate_linked_double_pay_fraud(self):
     db = self.MockDatabase()
     (block1, _, _, _) = TestBlocks.setup_validate()
     # Act
     db.add_block(block1)
     db.add_block(MultiChainBlock.create(db, block1.link_public_key, block1))
     block2 = MultiChainBlock.create(db, block1.link_public_key, block1)
     result = block2.validate(db)
     self.assertEqual(result[0], ValidationResult.invalid)
     self.assertIn("Double countersign fraud", result[1])
Пример #3
0
 def test_validate_linked_valid(self):
     db = self.MockDatabase()
     (block1, block2, _, _) = TestBlocks.setup_validate()
     db.add_block(block2)
     # Act
     db.add_block(MultiChainBlock.create(db, block1.link_public_key, block1))
     result = block1.validate(db)
     self.assertEqual(result[0], ValidationResult.valid)
Пример #4
0
 def test_create_genesis(self):
     key = ECCrypto().generate_key(u"curve25519")
     db = self.MockDatabase()
     block = MultiChainBlock.create(db, key.pub().key_to_bin(), link=None)
     self.assertEqual(block.previous_hash, GENESIS_HASH)
     self.assertEqual(block.sequence_number, GENESIS_SEQ)
     self.assertEqual(block.public_key, key.pub().key_to_bin())
     self.assertEqual(block.signature, EMPTY_SIG)
Пример #5
0
 def test_create_next(self):
     db = self.MockDatabase()
     prev = TestBlock()
     prev.sequence_number = GENESIS_SEQ
     db.add_block(prev)
     block = MultiChainBlock.create(db, prev.public_key, link=None)
     self.assertEqual(block.previous_hash, prev.hash)
     self.assertEqual(block.sequence_number, 2)
     self.assertEqual(block.public_key, prev.public_key)
Пример #6
0
 def test_validate_linked_down(self):
     db = self.MockDatabase()
     (block1, block2, _, _) = TestBlocks.setup_validate()
     db.add_block(block2)
     # Act
     db.add_block(MultiChainBlock.create(db, block1.link_public_key, block1))
     block1.down -= 5
     result = block1.validate(db)
     self.assertEqual(result[0], ValidationResult.invalid)
     self.assertIn("Down/up mismatch on linked block", result[1])
Пример #7
0
 def test_validate_linked_mismatch(self):
     db = self.MockDatabase()
     (block1, block2, _, _) = TestBlocks.setup_validate()
     # Act
     # db.add_block(MultiChainBlock.create(db, block1.link_public_key, block1))
     db.add_block(block1)
     block3 = MultiChainBlock.create(db, block2.link_public_key, block1)
     result = block3.validate(db)
     self.assertEqual(result[0], ValidationResult.invalid)
     self.assertIn("Public key mismatch on linked block", result[1])
Пример #8
0
    def __init__(self, previous=None):
        crypto = ECCrypto()
        up = random.randint(201, 220)
        down = random.randint(221, 240)
        other = crypto.generate_key(u"curve25519").pub().key_to_bin()

        if previous:
            self.key = previous.key
            MultiChainBlock.__init__(self, (
                up, down, previous.total_up + up, previous.total_down + down,
                previous.public_key, previous.sequence_number + 1, other, 0,
                previous.hash, 0, 0))
        else:
            self.key = crypto.generate_key(u"curve25519")
            MultiChainBlock.__init__(self, (
                up, down, random.randint(241, 260), random.randint(261, 280),
                self.key.pub().key_to_bin(), random.randint(50, 100), other, 0,
                sha256(str(random.randint(0, 100000))).digest(), 0, 0))
        self.sign(self.key)
Пример #9
0
 def test_create_link_genesis(self):
     key = ECCrypto().generate_key(u"curve25519")
     db = self.MockDatabase()
     link = TestBlock()
     db.add_block(link)
     block = MultiChainBlock.create(db, key.pub().key_to_bin(), link=link)
     self.assertEqual(block.previous_hash, GENESIS_HASH)
     self.assertEqual(block.sequence_number, GENESIS_SEQ)
     self.assertEqual(block.public_key, key.pub().key_to_bin())
     self.assertEqual(block.link_public_key, link.public_key)
     self.assertEqual(block.link_sequence_number, link.sequence_number)
Пример #10
0
    def _decode_half_block(placeholder, offset, data):
        """
        Decode an incoming half block message.
        :param placeholder:
        :param offset: Start of the HalfBlock message in the data.
        :param data: ByteStream containing the message.
        :return: (offset, HalfBlockPayload.impl)
        """
        if len(data) < offset + block_pack_size:
            raise DropPacket("Unable to decode the payload")

        return offset + block_pack_size, placeholder.meta.payload.implement(
            MultiChainBlock.unpack(data, offset))
Пример #11
0
 def test_unpack(self):
     block = MultiChainBlock.unpack('- So long and thanks for all the fish, so sad that it should come to this. - '
                                    'We tried to warn you all but oh dear! - You may not share our intellect, which '
                                    'might explain your disrespect, for all the natural wonders that grow around '
                                    'you. - So long, so long, and thanks for all the fish')
     self.assertEqual(block.up, 3251690667711950702)
     self.assertEqual(block.down, 7431046511915463784)
     self.assertEqual(block.total_up, 7020667011326177138)
     self.assertEqual(block.total_down, 2333265293611395173)
     self.assertEqual(block.public_key, ' fish, so sad that it should come to this. - We tried to warn you all but ')
     self.assertEqual(block.sequence_number, 1869095012)
     self.assertEqual(block.link_public_key,
                      'ear! - You may not share our intellect, which might explain your disrespec')
     self.assertEqual(block.link_sequence_number, 1949048934)
     self.assertEqual(block.previous_hash, 'or all the natural wonders that ')
     self.assertEqual(block.signature, 'grow around you. - So long, so long, and thanks for all the fish')
Пример #12
0
 def test_validate_not_sane_negatives(self):
     db = self.MockDatabase()
     block1 = MultiChainBlock()
     # Act
     block1.up = -10
     block1.down = -20
     block1.total_down = -10
     block1.total_up = -20
     result = block1.validate(db)
     self.assertEqual(result[0], ValidationResult.invalid)
     self.assertIn("Up field is negative", result[1])
     self.assertIn("Down field is negative", result[1])
     self.assertIn("Total up field is negative", result[1])
     self.assertIn("Total down field is negative", result[1])
Пример #13
0
 def test_validate_existing_link_public_key(self):
     # Arrange
     db = self.MockDatabase()
     (block1, block2, block3, _) = TestBlocks.setup_validate()
     db.add_block(block1)
     db.add_block(block2)
     db.add_block(block3)
     # Act
     block2 = MultiChainBlock(block2.pack_db_insert())
     block2.link_public_key = EMPTY_PK
     block2.sign(db.get(block2.public_key, block2.sequence_number).key)
     result = block2.validate(db)
     # Assert
     self.assertEqual(result[0], ValidationResult.invalid)
     self.assertIn('Linked public key is not valid', result[1])
Пример #14
0
 def test_validate_existing_hash(self):
     # Arrange
     db = self.MockDatabase()
     (block1, block2, block3, _) = TestBlocks.setup_validate()
     db.add_block(block1)
     db.add_block(block2)
     db.add_block(block3)
     # Act
     block2 = MultiChainBlock(block2.pack_db_insert())
     block2.previous_hash = sha256(str(random.randint(0, 100000))).digest()
     block2.sign(db.get(block2.public_key, block2.sequence_number).key)
     result = block2.validate(db)
     # Assert
     self.assertEqual(result[0], ValidationResult.invalid)
     self.assertIn('Previous hash is not equal to the hash id of the previous block', result[1])
Пример #15
0
    def sign_block(self,
                   candidate,
                   public_key=None,
                   bytes_up=None,
                   bytes_down=None,
                   linked=None):
        """
        Create, sign, persist and send a block signed message
        :param candidate: The peer with whom you have interacted, as a dispersy candidate
        :param bytes_up: The bytes you have uploaded to the peer in this interaction
        :param bytes_down: The bytes you have downloaded from the peer in this interaction
        :param linked: The block that the requester is asking us to sign
        """
        # NOTE to the future: This method reads from the database, increments and then writes back. If in some future
        # this method is allowed to execute in parallel, be sure to lock from before .create up to after .add_block
        assert bytes_up is None and bytes_down is None and linked is not None or \
            bytes_up is not None and bytes_down is not None and linked is None, \
            "Either provide a linked block or byte counts, not both"
        assert linked is None or linked.link_public_key == self.my_member.public_key, \
            "Cannot counter sign block not addressed to self"
        assert linked is None or linked.link_sequence_number == UNKNOWN_SEQ, \
            "Cannot counter sign block that is not a request"

        block = MultiChainBlock.create(self.persistence,
                                       self.my_member.public_key, linked)
        if linked is None:
            block.up = bytes_up
            block.down = bytes_down
            block.total_up += bytes_up
            block.total_down += bytes_down
            block.link_public_key = public_key
        block.sign(self.my_member.private_key)
        validation = block.validate(self.persistence)
        self.logger.info("Signed block to %s (%s) validation result %s",
                         block.link_public_key.encode("hex")[-8:], block,
                         validation)
        if validation[0] != ValidationResult.partial_next and validation[
                0] != ValidationResult.valid:
            self.logger.error("Signed block did not validate?! Result %s",
                              repr(validation))
        else:
            self.persistence.add_block(block)
            self.send_block(candidate, block)
Пример #16
0
 def test_validate_existing_fraud(self):
     # Arrange
     db = self.MockDatabase()
     (block1, block2, _, _) = TestBlocks.setup_validate()
     db.add_block(block1)
     db.add_block(block2)
     # Act
     block3 = MultiChainBlock(block2.pack_db_insert())
     block3.previous_hash = sha256(str(random.randint(0, 100000))).digest()
     block3.sign(block2.key)
     result = block3.validate(db)
     # Assert
     self.assertEqual(result[0], ValidationResult.invalid)
     self.assertIn("Double sign fraud", result[1])
Пример #17
0
 def test_validate_existing_total_down(self):
     # Arrange
     db = self.MockDatabase()
     (block1, block2, block3, _) = TestBlocks.setup_validate()
     db.add_block(block1)
     db.add_block(block2)
     db.add_block(block3)
     # Act
     block2 = MultiChainBlock(block2.pack_db_insert())
     block2.total_down += 10
     block2.sign(db.get(block2.public_key, block2.sequence_number).key)
     result = block2.validate(db)
     # Assert
     self.assertEqual(result[0], ValidationResult.invalid)
     self.assertIn('Total down is higher than expected compared to the next block', result[1])
Пример #18
0
 def test_pack(self):
     block = MultiChainBlock()
     block.up = 3251690667711950702
     block.down = 7431046511915463784
     block.total_up = 7020667011326177138
     block.total_down = 2333265293611395173
     block.public_key = ' fish, so sad that it should come to this. - We tried to warn you all but '
     block.sequence_number = 1869095012
     block.link_public_key = 'ear! - You may not share our intellect, which might explain your disrespec'
     block.link_sequence_number = 1949048934
     block.previous_hash = 'or all the natural wonders that '
     block.signature = 'grow around you. - So long, so long, and thanks for all the fish'
     self.assertEqual(block.pack(), '- So long and thanks for all the fish, so sad that it should come to this. - We'
                                    ' tried to warn you all but oh dear! - You may not share our intellect, which '
                                    'might explain your disrespect, for all the natural wonders that grow around you'
                                    '. - So long, so long, and thanks for all the fish')
Пример #19
0
 def test_hash(self):
     block = MultiChainBlock()
     self.assertEqual(block.hash, "\xa1c!\x14\x11\x14\xe4\xb1g\xebB\xae\xc1y-\x0eF\x1d\x94'\x1co\xc5\xe4g\x80\xf1"
                                  "\xc1z\xb0\x12\xd7")
Пример #20
0
 def _get(self, query, params):
     db_result = self.execute(_header + query, params).fetchone()
     return MultiChainBlock(db_result) if db_result else None
Пример #21
0
 def _getall(self, query, params):
     db_result = self.execute(_header + query, params).fetchall()
     return [MultiChainBlock(db_item) for db_item in db_result]
Пример #22
0
    def test_get_statistics(self):
        """
        Testing whether the API returns the correct statistics
        """
        block = MultiChainBlock()
        block.public_key = self.member.public_key
        block.link_public_key = "deadbeef".decode("HEX")
        block.link_sequence_number = 21
        block.up = 42
        block.down = 8
        block.total_up = 1024
        block.total_down = 2048
        block.sequence_number = 3
        block.previous_hash = "babecafe".decode("HEX")
        block.signature = "babebeef".decode("HEX")
        self.mc_community.persistence.add_block(block)

        def verify_response(response):
            response_json = json.loads(response)
            self.assertTrue("statistics" in response_json)
            stats = response_json["statistics"]
            self.assertEqual(stats["id"], self.member.public_key.encode("HEX"))
            self.assertEqual(stats["total_blocks"], 3)
            self.assertEqual(stats["total_up"], 1024)
            self.assertEqual(stats["total_down"], 2048)
            self.assertEqual(stats["peers_that_pk_helped"], 1)
            self.assertEqual(stats["peers_that_helped_pk"], 1)
            self.assertIn("latest_block", stats)
            self.assertNotEqual(stats["latest_block"]["insert_time"], "")
            self.assertEqual(stats["latest_block"]["hash"], block.hash.encode("HEX"))
            self.assertEqual(stats["latest_block"]["link_public_key"], "deadbeef")
            self.assertEqual(stats["latest_block"]["link_sequence_number"], 21)
            self.assertEqual(stats["latest_block"]["up"], 42)
            self.assertEqual(stats["latest_block"]["down"], 8)

        self.should_check_equality = False
        return self.do_request('multichain/statistics', expected_code=200).addCallback(verify_response)