Example #1
0
    def test_verify_tree(self):
        raw_leaves = [secrets.token_bytes(16) for _ in range(16)]

        m = MerkleTree(raw_leaves)

        tree_nodes = m.nodes[len(m.nodes) // 2:]
        tree_hash = m.hash_of_nodes()

        self.assertTrue(MerkleTree.verify_tree(tree_nodes, tree_hash))
Example #2
0
    def test_verify_tree_invalid(self):
        raw_leaves = [secrets.token_bytes(16) for _ in range(16)]

        m = MerkleTree(raw_leaves)

        # Set the last leaf to a random value obviously different then whatever was used to build the tree
        # this should cause validation to fail
        bad_leaves = m.leaves
        bad_leaves[-1] = secrets.token_bytes(16)

        self.assertFalse(MerkleTree.verify_tree(bad_leaves, m.root))
Example #3
0
    def validate_block_contender(self, block: BlockContender) -> bool:
        """
        Helper method to validate a block contender. For a block contender to be valid it must:
        1) Have a provable merkle tree, ie. all nodes must be hash of (left child + right child)
        2) Be signed by at least 2/3 of the top 32 delegates
        :param block_contender: The BlockContender to validate
        :return: True if the BlockContender is valid, false otherwise
        """
        def _validate_sigs(signatures, msg) -> bool:
            for sig in signatures:
                self.log.info("mn verifying signature: {}".format(sig))
                if not sig.verify(msg, sig.sender):
                    self.log.error(
                        "!!!! Oh no why couldnt we verify sig {}???".format(
                            sig))
                    return False
            return True

        # Development sanity checks (these should be removed in production)
        assert len(
            block.nodes
        ) >= 1, "Masternode got block contender with no nodes! {}".format(
            block)
        assert len(block.signatures) >= Constants.Testnet.Majority, \
            "Received a block contender with only {} signatures (which is less than a majority of {}"\
            .format(len(block.signatures), Constants.Testnet.Majority)

        # TODO -- ensure that this block contender's previous block is this Masternode's current block...

        # Prove Merkle Tree
        hash_of_nodes = MerkleTree.hash_nodes(block.nodes)
        tx_hashes = block.nodes[len(block.nodes) // 2:]
        if not MerkleTree.verify_tree(tx_hashes, hash_of_nodes):
            self.log.error(
                "\n\n\n\nCOULD NOT VERIFY MERKLE TREE FOR BLOCK CONTENDER {}\n\n\n"
                .format(block))
            return False

        # Validate signatures
        if not _validate_sigs(block.signatures, hash_of_nodes):
            self.log.error(
                "MN COULD NOT VALIDATE SIGNATURES FOR CONTENDER {}".format(
                    block))
            return False

        return True
Example #4
0
    def test_verify_tree(self):
        raw_leaves = [secrets.token_bytes(16) for _ in range(16)]

        m = MerkleTree(raw_leaves)

        self.assertTrue(MerkleTree.verify_tree(m.leaves, m.root))