def create_negative_gossip_transaction(number_of_block, node_private):
     tx = NegativeGossipTransaction()
     tx.timestamp = Time.get_current_time()
     tx.number_of_block = number_of_block
     tx.pubkey = Private.publickey(node_private)
     tx.signature = Private.sign(tx.get_hash(), node_private)
     return tx
예제 #2
0
 def sign_block(block, private):
     block_hash = block.get_hash()
     signature = Private.sign(block_hash, private)
     signed_block = SignedBlock()
     signed_block.set_block(block)
     signed_block.set_signature(signature)
     return signed_block
 def create_positive_gossip_transaction(block_hash, node_private):
     tx = PositiveGossipTransaction()
     tx.timestamp = Time.get_current_time()
     tx.block_hash = block_hash
     tx.pubkey = Private.publickey(node_private)
     tx.signature = Private.sign(tx.get_hash(), node_private)
     return tx
 def create_public_key_transaction(generated_private, epoch_hash,
                                   validator_index, node_private):
     tx = PublicKeyTransaction()
     tx.generated_pubkey = Private.publickey(generated_private)
     tx.pubkey_index = validator_index
     tx.signature = Private.sign(tx.get_signing_hash(epoch_hash),
                                 node_private)
     return tx
 def create_commit_random_transaction(rand, pubkey_index, epoch_hash,
                                      node_private):
     tx = CommitRandomTransaction()
     tx.rand = rand
     tx.pubkey_index = pubkey_index
     tx.signature = Private.sign(tx.get_signing_hash(epoch_hash),
                                 node_private)
     return tx
 def create_payment_transaction(from_tx, amount, to, node_private):
     tx = PaymentTransaction()
     tx.from_tx = from_tx
     tx.amount = amount
     tx.to = to
     tx.pubkey = Private.publickey(node_private)
     tx.signature = Private.sign(tx.get_hash(), node_private)
     return tx
 def create_split_random_transaction(encoded_splits, pubkey_index,
                                     epoch_hash, node_private):
     tx = SplitRandomTransaction()
     tx.pieces = encoded_splits
     tx.pubkey_index = pubkey_index
     tx.signature = Private.sign(tx.get_signing_hash(epoch_hash),
                                 node_private)
     return tx
예제 #8
0
    def test_pack_parse_penalty_transaction(self):
        original = PenaltyTransaction()
        original.violator_pubkey = Private.publickey(Private.generate())
        original.conflicts = [os.urandom(32), os.urandom(32), os.urandom(32)]
        original.signature = Private.sign(original.get_hash(),
                                          Private.generate())

        raw = original.pack()
        restored = PenaltyTransaction()
        restored.parse(raw)

        self.assertEqual(original.get_hash(), restored.get_hash())
예제 #9
0
    def test_pack_parse_stakerelease_transaction(self):
        private = Private.generate()
        original = StakeReleaseTransaction()
        original.pubkey = Private.publickey(private)
        original.signature = Private.sign(original.get_hash(),
                                          Private.generate())

        raw = original.pack()
        restored = StakeReleaseTransaction()
        restored.parse(raw)

        self.assertEqual(original.get_hash(), restored.get_hash())
예제 #10
0
    def test_pack_parse_stakehold_transaction(self):
        private = Private.generate()
        original = StakeHoldTransaction()
        original.amount = 1000
        original.pubkey = Private.publickey(private)
        original.signature = Private.sign(original.get_hash(), private)

        raw = original.pack()
        restored = StakeHoldTransaction()
        restored.parse(raw)

        self.assertEqual(original.get_hash(), restored.get_hash())
    def test_parse_pack_gossip_negative(self):
        private = Private.generate()
        original = NegativeGossipTransaction()
        original.pubkey = Private.publickey(private)
        original.timestamp = Time.get_current_time()
        original.number_of_block = 47
        original.signature = Private.sign(original.get_hash(), private)

        raw = original.pack()
        restored = NegativeGossipTransaction()
        restored.parse(raw)

        self.assertEqual(original.get_hash(), restored.get_hash())
    def test_pack_parse_penalty_gossip_transaction(self):
        private = Private.generate()
        original = PenaltyGossipTransaction()
        original.timestamp = Time.get_current_time()
        block = BlockFactory.create_block_with_timestamp(
            [], timestamp=original.timestamp)

        gossip_positive_tx = PositiveGossipTransaction()
        gossip_positive_tx.pubkey = Private.publickey(private)
        gossip_positive_tx.timestamp = Time.get_current_time()
        gossip_positive_tx.block_hash = BlockFactory.sign_block(
            block, private).get_hash()
        gossip_positive_tx.signature = Private.sign(original.get_hash(),
                                                    private)

        gossip_negative_tx = NegativeGossipTransaction()
        gossip_negative_tx.pubkey = Private.publickey(private)
        gossip_negative_tx.timestamp = Time.get_current_time()
        gossip_negative_tx.number_of_block = 47
        gossip_negative_tx.signature = Private.sign(original.get_hash(),
                                                    private)

        original.conflicts = [
            gossip_positive_tx.get_hash(),
            gossip_negative_tx.get_hash()
        ]
        original.signature = Private.sign(original.get_hash(), private)

        original.block_hash = BlockFactory.sign_block(block,
                                                      private).get_hash()

        raw = original.pack()
        restored = PenaltyGossipTransaction()
        restored.parse(raw)

        self.assertEqual(original.get_hash(), restored.get_hash())
    def test_split_pack_unpack(self):
        dummy_private = Private.generate()

        original = SplitRandomTransaction()
        original.pieces = [os.urandom(128), os.urandom(127), os.urandom(128)]
        original.pubkey_index = 0
        original.signature = Private.sign(
            original.get_signing_hash(b"epoch_hash"), dummy_private)

        raw = original.pack()
        restored = SplitRandomTransaction()
        restored.parse(raw)

        self.assertEqual(original.get_hash(), restored.get_hash())
        self.assertEqual(original.get_signing_hash(b"epoch_hash"),
                         restored.get_signing_hash(b"epoch_hash"))
    def test_parse_pack_gossip_positive(self):
        private = Private.generate()
        original = PositiveGossipTransaction()
        original.pubkey = Private.publickey(private)
        original.timestamp = Time.get_current_time()

        block = BlockFactory.create_block_with_timestamp(
            [], timestamp=original.timestamp)
        original.block_hash = BlockFactory.sign_block(block,
                                                      private).get_hash()
        original.signature = Private.sign(original.get_hash(), private)

        raw = original.pack()
        restored = PositiveGossipTransaction()
        restored.parse(raw)

        self.assertEqual(original.get_hash(), restored.get_hash())
    def create_dummy_commit_reveal(random_bytes, epoch_hash):
        node_private = Private.generate()

        private = Private.generate()

        encoded = Private.encrypt(random_bytes, private)

        commit = CommitRandomTransaction()
        commit.rand = encoded
        commit.pubkey_index = 10
        commit.signature = Private.sign(commit.get_signing_hash(epoch_hash),
                                        node_private)

        reveal = RevealRandomTransaction()
        reveal.commit_hash = commit.get_hash()
        reveal.key = Keys.to_bytes(private)

        return commit, reveal
    def test_pack_parse_commit_transaction(self):
        for i in range(10):
            dummy_private = Private.generate()
            original = CommitRandomTransaction()
            original.rand = Private.encrypt(os.urandom(32), dummy_private)
            original.pubkey_index = i
            original.signature = Private.sign(
                original.get_signing_hash(b"epoch_hash"), dummy_private)

            raw = original.pack()
            restored = CommitRandomTransaction()
            restored.parse(raw)

            self.assertEqual(TransactionParser.pack(original),
                             TransactionParser.pack(restored))
            self.assertEqual(original.get_hash(), restored.get_hash())
            self.assertEqual(original.get_signing_hash(b"epoch_hash"),
                             restored.get_signing_hash(b"epoch_hash"))
    def test_penalty(self):
        dag = Dag(0)
        epoch = Epoch(dag)
        permissions = Permissions(epoch)
        node_private = Private.generate()

        initial_validators = Validators.read_genesis_validators_from_file()

        genesis_hash = dag.genesis_block().get_hash()

        last_block_number = Epoch.get_epoch_end_block_number(1)
        prev_hash = ChainGenerator.fill_with_dummies(
            dag, genesis_hash, range(1, last_block_number))

        block = BlockFactory.create_block_with_timestamp(
            [prev_hash], BLOCK_TIME * last_block_number)
        tx = PenaltyTransaction()
        tx.conflicts = [prev_hash]
        tx.signature = Private.sign(tx.get_hash(), node_private)
        block.system_txs = [tx]
        signed_block = BlockFactory.sign_block(block, node_private)
        dag.add_signed_block(last_block_number, signed_block)

        initial_validators_order = permissions.get_signers_indexes(
            genesis_hash)
        # we substract two here: one because it is last but one block
        # and one, because epoch starts from 1
        validator_index_to_penalize = initial_validators_order[
            last_block_number - 2]

        resulting_validators = permissions.get_validators(block.get_hash())

        self.assertNotEqual(len(initial_validators), len(resulting_validators))

        initial_validators.pop(validator_index_to_penalize)

        init_pubkeys = list(
            map(lambda validator: validator.public_key, initial_validators))
        result_pubkeys = list(
            map(lambda validator: validator.public_key, resulting_validators))

        self.assertEqual(init_pubkeys, result_pubkeys)
    def test_stake_release_by_genesis_validator(self):
        # base initialization
        dag = Dag(0)
        epoch = Epoch(dag)
        permissions = Permissions(epoch)
        node_private = Private.generate()

        initial_validators = Validators.read_genesis_validators_from_file()

        genesis_hash = dag.genesis_block().get_hash()
        prev_hash = genesis_hash
        for i in range(1, 9):
            block = BlockFactory.create_block_with_timestamp([prev_hash],
                                                             BLOCK_TIME * i)
            signed_block = BlockFactory.sign_block(block, node_private)
            dag.add_signed_block(i, signed_block)
            prev_hash = block.get_hash()

        # get one of validators
        genesis_validator = initial_validators[9]

        # create stake release transaction for new stakeholder
        tx_release = StakeReleaseTransaction()
        tx_release.pubkey = Keys.to_bytes(genesis_validator.public_key)
        tx_release.signature = Private.sign(tx_release.get_hash(),
                                            node_private)

        # append signed stake release transaction
        block.system_txs.append(tx_release)

        # sign block by one of validators
        signed_block = BlockFactory.sign_block(block, node_private)
        # add signed block to DAG
        dag.add_signed_block(19, signed_block)

        resulting_validators = permissions.get_validators(block.get_hash())
        pub_keys = []
        for validator in resulting_validators:
            pub_keys.append(validator.public_key)
        self.assertNotIn(genesis_validator.public_key, pub_keys)
    def test_hold_stake(self):
        dag = Dag(0)
        epoch = Epoch(dag)
        permissions = Permissions(epoch)
        node_private = Private.generate()

        initial_validators = Validators.read_genesis_validators_from_file()

        genesis_hash = dag.genesis_block().get_hash()
        prev_hash = genesis_hash
        for i in range(1, 9):
            block = BlockFactory.create_block_with_timestamp([prev_hash],
                                                             BLOCK_TIME * i)
            signed_block = BlockFactory.sign_block(block, node_private)
            dag.add_signed_block(i, signed_block)
            prev_hash = block.get_hash()

        block = BlockFactory.create_block_with_timestamp([prev_hash],
                                                         BLOCK_TIME * 9)

        tx = StakeHoldTransaction()
        tx.amount = 1000
        node_new_private = Private.generate()

        tx.pubkey = Private.publickey(node_new_private)
        tx.signature = Private.sign(tx.get_hash(), node_new_private)

        block.system_txs.append(tx)
        signed_block = BlockFactory.sign_block(block, node_private)
        dag.add_signed_block(9, signed_block)

        resulting_validators = permissions.get_validators(block.get_hash())
        pub_keys = []
        for validator in resulting_validators:
            pub_keys.append(validator.public_key)

        self.assertIn(Private.publickey(node_new_private), pub_keys)
    def test_remove_from_validators_by_penalty_gossip(self):
        # base initialization
        dag = Dag(0)
        epoch = Epoch(dag)
        permissions = Permissions(epoch)
        node_private = Private.generate()

        initial_validators = Validators.read_genesis_validators_from_file()

        genesis_hash = dag.genesis_block().get_hash()
        prev_hash = genesis_hash
        for i in range(1, 9):
            block = BlockFactory.create_block_with_timestamp([prev_hash],
                                                             BLOCK_TIME * i)
            signed_block = BlockFactory.sign_block(block, node_private)
            dag.add_signed_block(i, signed_block)
            prev_hash = block.get_hash()

        # get one of validators
        genesis_validator_private = Private.generate()
        genesis_validator_public = initial_validators[9].public_key

        # put to 10 block gossip+ AND gossip- by one node
        block = BlockFactory.create_block_with_timestamp([prev_hash],
                                                         BLOCK_TIME * 10)

        gossip_negative_tx = NegativeGossipTransaction()
        gossip_negative_tx.pubkey = genesis_validator_public
        gossip_negative_tx.timestamp = Time.get_current_time()
        gossip_negative_tx.number_of_block = 5
        gossip_negative_tx.signature = Private.sign(
            gossip_negative_tx.get_hash(), genesis_validator_private)
        # create and add to block negative gossip
        block.system_txs.append(gossip_negative_tx)

        gossip_positive_tx = PositiveGossipTransaction()
        gossip_positive_tx.pubkey = genesis_validator_public
        gossip_positive_tx.timestamp = Time.get_current_time()
        gossip_positive_tx.block_hash = dag.blocks_by_number[5][0].get_hash()
        gossip_positive_tx.signature = Private.sign(
            gossip_positive_tx.get_hash(), genesis_validator_private)
        # create and add to block positive gossip for same number 5 block
        block.system_txs.append(gossip_positive_tx)

        signed_block = BlockFactory.sign_block(block,
                                               genesis_validator_private)
        dag.add_signed_block(10, signed_block)
        prev_hash = block.get_hash()
        # --------------------------------------------------

        # put to 11 block penalty gossip
        block = BlockFactory.create_block_with_timestamp([prev_hash],
                                                         BLOCK_TIME * 11)
        penalty_gossip_tx = PenaltyGossipTransaction()
        penalty_gossip_tx.timestamp = Time.get_current_time()
        penalty_gossip_tx.conflicts = [
            gossip_positive_tx.get_hash(),
            gossip_negative_tx.get_hash()
        ]
        # set genesis validator for sign penalty gossip
        penalty_gossip_tx.signature = Private.sign(
            penalty_gossip_tx.get_hash(), genesis_validator_private)
        block.system_txs.append(penalty_gossip_tx)

        signed_block = BlockFactory.sign_block(block,
                                               genesis_validator_private)
        dag.add_signed_block(11, signed_block)
        prev_hash = block.get_hash()
        # --------------------------------------------------

        # verify that genesis node is steel in validators list
        current_epoch_hash = epoch.get_epoch_hashes()
        # for now we DO NOT NEED to recalculate validators (send genesis block hash)
        resulting_validators = permissions.get_validators(
            current_epoch_hash.get(prev_hash))
        pub_keys = []
        for validator in resulting_validators:
            pub_keys.append(validator.public_key)
        self.assertIn(genesis_validator_public, pub_keys)

        # produce epoch till end
        from chain.params import ROUND_DURATION
        for i in range(12, (ROUND_DURATION * 6 + 4)):
            block = BlockFactory.create_block_with_timestamp([prev_hash],
                                                             BLOCK_TIME * i)
            signed_block = BlockFactory.sign_block(block, node_private)
            dag.add_signed_block(i, signed_block)
            prev_hash = block.get_hash()

        # check for new epoch
        self.assertTrue(epoch.is_new_epoch_upcoming(i))
        self.assertTrue(epoch.current_epoch == 2)

        # recalculate validators for last block hash
        resulting_validators = permissions.get_validators(prev_hash)
        pub_keys = []
        for validator in resulting_validators:
            pub_keys.append(validator.public_key)

        self.assertNotIn(genesis_validator_public, pub_keys)
    def test_secret_sharing_rounds(self):
        dag = Dag(0)
        epoch = Epoch(dag)

        dummy_private = Private.generate()

        signers = []
        for i in range(0, ROUND_DURATION + 1):
            signers.append(Private.generate())

        private_keys = []

        block_number = 1
        genesis_hash = dag.genesis_block().get_hash()
        prev_hash = genesis_hash
        signer_index = 0
        for i in Epoch.get_round_range(1, Round.PUBLIC):
            private = Private.generate()
            private_keys.append(private)

            signer = signers[signer_index]
            pubkey_tx = PublicKeyTransaction()
            pubkey_tx.generated_pubkey = Private.publickey(private)
            pubkey_tx.pubkey_index = signer_index
            pubkey_tx.signature = Private.sign(
                pubkey_tx.get_signing_hash(genesis_hash), signer)

            block = Block()
            block.timestamp = i * BLOCK_TIME
            block.prev_hashes = [prev_hash]
            block.system_txs = [pubkey_tx]
            signed_block = BlockFactory.sign_block(block, signer)
            dag.add_signed_block(i, signed_block)
            signer_index += 1
            prev_hash = block.get_hash()

        prev_hash = ChainGenerator.fill_with_dummies(
            dag, prev_hash, Epoch.get_round_range(1, Round.COMMIT))

        public_keys = []
        for private in private_keys:
            public_keys.append(Private.publickey(private))

        randoms_list = []
        expected_random_pieces = []
        for i in Epoch.get_round_range(1, Round.SECRETSHARE):
            random_bytes = os.urandom(32)
            random_value = int.from_bytes(random_bytes, byteorder='big')
            split_random_tx = SplitRandomTransaction()
            splits = split_secret(random_bytes, 2, 3)
            encoded_splits = encode_splits(splits, public_keys)
            split_random_tx.pieces = encoded_splits
            split_random_tx.pubkey_index = 0
            expected_random_pieces.append(split_random_tx.pieces)
            split_random_tx.signature = Private.sign(pubkey_tx.get_hash(),
                                                     dummy_private)
            block = Block()
            block.timestamp = i * BLOCK_TIME
            block.prev_hashes = [prev_hash]
            block.system_txs = [split_random_tx]
            signed_block = BlockFactory.sign_block(block, dummy_private)
            dag.add_signed_block(i, signed_block)
            randoms_list.append(random_value)
            prev_hash = block.get_hash()

        expected_seed = sum_random(randoms_list)

        prev_hash = ChainGenerator.fill_with_dummies(
            dag, prev_hash, Epoch.get_round_range(1, Round.REVEAL))

        signer_index = 0
        private_key_index = 0
        raw_private_keys = []
        for i in Epoch.get_round_range(1, Round.PRIVATE):
            private_key_tx = PrivateKeyTransaction()
            private_key_tx.key = Keys.to_bytes(private_keys[private_key_index])
            raw_private_keys.append(private_key_tx.key)
            signer = signers[signer_index]
            block = Block()
            block.system_txs = [private_key_tx]
            block.prev_hashes = [prev_hash]
            block.timestamp = block_number * BLOCK_TIME
            signed_block = BlockFactory.sign_block(block, signer)
            dag.add_signed_block(i, signed_block)
            signer_index += 1
            private_key_index += 1
            prev_hash = block.get_hash()

        prev_hash = ChainGenerator.fill_with_dummies(
            dag, prev_hash, Epoch.get_round_range(1, Round.FINAL))

        top_block_hash = dag.get_top_blocks_hashes()[0]

        random_splits = epoch.get_random_splits_for_epoch(top_block_hash)
        self.assertEqual(expected_random_pieces, random_splits)

        restored_randoms = []
        for i in range(0, len(random_splits)):
            random = decode_random(random_splits[i],
                                   Keys.list_from_bytes(raw_private_keys))
            restored_randoms.append(random)

        self.assertEqual(randoms_list, restored_randoms)

        seed = epoch.extract_shared_random(top_block_hash)
        self.assertEqual(expected_seed, seed)
 def create_stake_release_transaction(node_private):
     tx = StakeReleaseTransaction()
     tx.pubkey = Private.publickey(node_private)
     tx.signature = Private.sign(tx.get_hash(), node_private)
     return tx
 def create_penalty_transaction(conflicts, node_private):
     tx = PenaltyTransaction()
     tx.conflicts = conflicts
     tx.signature = Private.sign(tx.get_hash(), node_private)
     return tx
 def create_penalty_gossip_transaction(conflict, node_private):
     tx = PenaltyGossipTransaction()
     tx.timestamp = Time.get_current_time()
     tx.conflicts = conflict
     tx.signature = Private.sign(tx.get_hash(), node_private)
     return tx
 def create_stake_hold_transaction(amount, node_private):
     tx = StakeHoldTransaction()
     tx.amount = amount
     tx.pubkey = Private.publickey(node_private)
     tx.signature = Private.sign(tx.get_hash(), node_private)
     return tx
    def test_release_stake(self):
        # base initialization
        dag = Dag(0)
        epoch = Epoch(dag)
        permissions = Permissions(epoch)
        node_private = Private.generate()

        initial_validators = Validators.read_genesis_validators_from_file()

        genesis_hash = dag.genesis_block().get_hash()
        prev_hash = genesis_hash
        for i in range(1, 9):
            block = BlockFactory.create_block_with_timestamp([prev_hash],
                                                             BLOCK_TIME * i)
            signed_block = BlockFactory.sign_block(block, node_private)
            dag.add_signed_block(i, signed_block)
            prev_hash = block.get_hash()

        block = BlockFactory.create_block_with_timestamp([prev_hash],
                                                         BLOCK_TIME * 9)

        # create new node for stake hold
        new_node_private = Private.generate()
        new_node_public = Private.publickey(new_node_private)

        # create transaction for stake hold for new node
        tx_hold = StakeHoldTransaction()
        tx_hold.amount = 2000
        tx_hold.pubkey = Keys.to_bytes(new_node_public)
        tx_hold.signature = Private.sign(tx_hold.get_hash(), new_node_private)

        # append signed stake hold transaction
        block.system_txs.append(tx_hold)

        # sign block by one of validators
        signed_block = BlockFactory.sign_block(block, node_private)
        # add signed block to DAG
        dag.add_signed_block(9, signed_block)

        resulting_validators = permissions.get_validators(block.get_hash())
        pub_keys = []
        for validator in resulting_validators:
            pub_keys.append(validator.public_key)
        self.assertIn(new_node_public, pub_keys)

        # add blocks for new epoch
        for i in range(10, 18):
            block = BlockFactory.create_block_with_timestamp([prev_hash],
                                                             BLOCK_TIME * i)
            signed_block = BlockFactory.sign_block(block, node_private)
            dag.add_signed_block(i, signed_block)
            prev_hash = block.get_hash()

        # create stake release transaction for new stakeholder
        tx_release = StakeReleaseTransaction()
        tx_release.pubkey = Keys.to_bytes(new_node_public)
        tx_release.signature = Private.sign(tx_hold.get_hash(),
                                            new_node_private)

        # append signed stake release transaction
        block.system_txs.append(tx_release)

        # sign block by one of validators
        signed_block = BlockFactory.sign_block(block, node_private)
        # add signed block to DAG
        dag.add_signed_block(19, signed_block)

        # verify that new stake holder now is NOT in validators list (after stake release transaction signed by holder)
        resulting_validators = permissions.get_validators(block.get_hash())
        pub_keys = []
        for validator in resulting_validators:
            pub_keys.append(validator.public_key)
        self.assertNotIn(new_node_public, pub_keys)