Example #1
0
    def make_st_tx(self, blocknumber, first_hash):
        balance = self.chain.block_chain_buffer.get_stxn_state(blocknumber, self.chain.mining_address)[1]
        if balance < config.dev.minimum_staking_balance_required:
            logger.warning('Staking not allowed due to insufficient balance')
            logger.warning('Balance %s', balance)
            return


        slave_xmss = self.chain.block_chain_buffer.get_next_slave_xmss(blocknumber)
        if not slave_xmss:
            return

        st = StakeTransaction().create(
            blocknumber=blocknumber,
            xmss=self.chain.wallet.address_bundle[0].xmss,
            slave_public_key=slave_xmss.pk(),
            first_hash=first_hash,
            balance=balance
        )
        self.p2pFactory.send_st_to_peers(st)
        for num in range(len(self.chain.transaction_pool)):
            t = self.chain.transaction_pool[num]
            if t.subtype == qrl.core.Transaction_subtypes.TX_SUBTYPE_STAKE and st.hash == t.hash:
                if st.get_message_hash() == t.get_message_hash():
                    return
                self.chain.remove_tx_from_pool(t)
                break

        self.chain.add_tx_to_pool(st)
        self.chain.wallet.save_wallet()
Example #2
0
    def pre_pos_1(self, data=None):  # triggered after genesis for block 1..
        logger.info('pre_pos_1')
        # are we a staker in the stake list?

        if self.chain.mining_address not in self.chain.m_blockchain[0].stake_list:
            logger.info('not in stake list..no further pre_pos_x calls')
            return

        logger.info('mining address: %s in the genesis.stake_list', self.chain.mining_address)
        xmss = self.chain.wallet.address_bundle[0].xmss
        tmphc = hashchain(xmss.get_seed_private(), epoch=0)
        self.chain.hash_chain = tmphc.hashchain
        self.chain.block_chain_buffer.hash_chain[0] = tmphc.hashchain

        tmpbalance = self.chain.state.state_balance(self.chain.mining_address)
        slave_xmss = self.chain.block_chain_buffer.get_slave_xmss(0)
        if not slave_xmss:
            logger.info('Waiting for SLAVE XMSS to be done')
            reactor.callLater(5, self.pre_pos_1)
            return

        st = StakeTransaction().create(blocknumber=0,
                                       xmss=self.chain.wallet.address_bundle[0].xmss,
                                       slave_public_key=slave_xmss.pk(),
                                       hashchain_terminator=tmphc.hc_terminator,
                                       first_hash=tmphc.hashchain[-1][-2],
                                       balance=tmpbalance)

        self.chain.add_tx_to_pool(st)
        # send the stake tx to generate hashchain terminators for the staker addresses..
        self.p2pFactory.send_st_to_peers(st)
        logger.info('await delayed call to build staker list from genesis')
        reactor.callLater(5, self.pre_pos_2, st)
Example #3
0
    def test_create(self):
        alice_xmss = get_alice_xmss()
        slave_xmss = XMSS(alice_xmss.height, alice_xmss.get_seed())

        staking_address = bytes(alice_xmss.get_address().encode())

        h0 = sha256(b'hashchain_seed')
        h1 = sha256(h0)
        h2 = sha256(h1)

        stake_transaction = StakeTransaction.create(activation_blocknumber=0,
                                                    xmss=alice_xmss,
                                                    slavePK=slave_xmss.pk(),
                                                    hashchain_terminator=h2)

        sv = StakeValidator(100, stake_transaction)

        self.assertEqual(staking_address, sv.address)
        self.assertEqual(slave_xmss.pk(), sv.slave_public_key)
        self.assertEqual(h2, sv.terminator_hash)

        self.assertEqual(100, sv.balance)
        self.assertEqual(0, sv.nonce)
        self.assertFalse(sv.is_banned)
        self.assertTrue(sv.is_active)
Example #4
0
 def test_to_json(self):
     tx = StakeTransaction.create(activation_blocknumber=2,
                                  xmss=self.alice,
                                  slavePK=self.bob.pk(),
                                  hashchain_terminator=sha256(b'T1'))
     txjson = tx.to_json()
     self.assertEqual(json.loads(test_json_Stake), json.loads(txjson))
Example #5
0
    def test_negative_balance(self):
        alice_xmss = get_alice_xmss()
        slave_xmss = XMSS(alice_xmss.height, alice_xmss.get_seed())
        stake_transaction = StakeTransaction.create(activation_blocknumber=0,
                                                    xmss=alice_xmss,
                                                    slavePK=slave_xmss.pk())

        with self.assertRaises(ValueError):
            StakeValidator(-1, stake_transaction)
Example #6
0
    def pre_pos_1(self, data=None):  # triggered after genesis for block 1..
        logger.info('pre_pos_1')
        # are we a staker in the stake list?
        genesis_block = self.buffered_chain.get_block(0)
        found = False
        for genesisBalance in genesis_block.genesis_balance:
            if genesisBalance.address.encode(
            ) == self.buffered_chain.staking_address:
                logger.info('Found in Genesis Address %s %s',
                            genesisBalance.address.encode(),
                            genesisBalance.balance)
                found = True
                break

        if not found:
            return

        logger.info('mining address: %s in the genesis.stake_list',
                    self.buffered_chain.staking_address)
        xmss = self.buffered_chain.wallet.address_bundle[0].xmss
        tmphc = hashchain(xmss.get_seed_private(), epoch=0)
        self.buffered_chain.hash_chain[0] = tmphc.hashchain

        slave_xmss = self.buffered_chain.get_slave_xmss(0)
        if not slave_xmss:
            logger.info('Waiting for SLAVE XMSS to be done')
            reactor.callLater(5, self.pre_pos_1)
            return

        signing_xmss = self.buffered_chain.wallet.address_bundle[0].xmss
        st = StakeTransaction.create(activation_blocknumber=1,
                                     xmss=signing_xmss,
                                     slavePK=slave_xmss.pk(),
                                     hashchain_terminator=tmphc.hc_terminator)
        st.sign(signing_xmss)

        self.buffered_chain.tx_pool.add_tx_to_pool(st)

        # send the stake tx to generate hashchain terminators for the staker addresses..
        self.p2p_factory.broadcast_st(st)

        vote = Vote.create(
            addr_from=self.buffered_chain.wallet.address_bundle[0].address,
            blocknumber=0,
            headerhash=genesis_block.headerhash,
            xmss=slave_xmss)

        vote.sign(slave_xmss)

        self.buffered_chain.add_vote(vote)

        # send the stake votes for genesis block
        self.p2p_factory.broadcast_vote(vote)

        logger.info('await delayed call to build staker list from genesis')
        reactor.callLater(5, self.pre_pos_2, st)
    def test_getStakers(self):
        db_state = Mock(spec=State)
        db_state.stake_validators_tracker = Mock(spec=StakeValidatorsTracker)
        db_state.stake_validators_tracker.sv_dict = dict()

        p2p_factory = Mock(spec=P2PFactory)
        buffered_chain = Mock(spec=BufferedChain)
        buffered_chain.tx_pool = Mock()
        buffered_chain.get_block = Mock()
        buffered_chain._chain = Mock()

        qrlnode = QRLNode(db_state)
        qrlnode.set_p2pfactory(p2p_factory)
        qrlnode.set_chain(buffered_chain)

        service = PublicAPIService(qrlnode)
        context = Mock(spec=ServicerContext)

        request = qrl_pb2.GetStakersReq(filter=qrl_pb2.GetStakersReq.CURRENT,
                                        offset=0,
                                        quantity=3)

        response = service.GetStakers(request=request, context=context)
        context.set_code.assert_not_called()
        context.set_details.assert_not_called()
        self.assertEqual(0, len(response.stakers))

        # Add a few validators
        stake_tx = StakeTransaction.create(1, get_alice_xmss(),
                                           get_bob_xmss().pk(),
                                           sha256(b'terminator'))

        expected_address = bytes(get_alice_xmss().get_address().encode())
        db_state.get_address = MagicMock(
            return_value=AddressState.create(address=expected_address,
                                             nonce=1,
                                             balance=100,
                                             pubhashes=[],
                                             tokens=dict()))

        db_state.get_address_tx_hashes = MagicMock(return_value=[])

        validator1 = StakeValidator.create(100, stake_tx)

        db_state.stake_validators_tracker.sv_dict[
            validator1.address] = validator1
        request = qrl_pb2.GetStakersReq(filter=qrl_pb2.GetStakersReq.CURRENT,
                                        offset=0,
                                        quantity=3)

        response = service.GetStakers(request=request, context=context)
        context.set_code.assert_not_called()
        context.set_details.assert_not_called()
        self.assertEqual(1, len(response.stakers))
        self.assertEqual(expected_address,
                         response.stakers[0].address_state.address)
Example #8
0
    def test_invalid_balance(self):
        alice_xmss = get_alice_xmss()
        slave_xmss = XMSS(alice_xmss.height, alice_xmss.get_seed())
        stake_transaction = StakeTransaction.create(activation_blocknumber=0,
                                                    xmss=alice_xmss,
                                                    slavePK=slave_xmss.pk())

        with self.assertRaises(ValueError):
            StakeValidator(config.dev.minimum_staking_balance_required - 1,
                           stake_transaction)
Example #9
0
    def test_get_message_hash(self):
        tx = StakeTransaction.create(activation_blocknumber=2,
                                     xmss=self.alice,
                                     slavePK=self.bob.pk(),
                                     hashchain_terminator=sha256(b'T1'))

        # Currently, a Transaction's message is always blank (what is it used for?)
        self.assertEqual(
            '06b0fcaf2e2ca69299a8a2ce32f0c05cd14cd61e25a9e324ffad8abc5a88aa7f',
            bin2hstr(tuple(tx.get_message_hash())))
Example #10
0
    def test_empty_terminator(self):
        alice_xmss = get_alice_xmss()
        slave_xmss = XMSS(alice_xmss.height, alice_xmss.get_seed())
        stake_transaction = StakeTransaction.create(activation_blocknumber=0,
                                                    xmss=alice_xmss,
                                                    slavePK=slave_xmss.pk())

        stake_transaction._data.stake.hash = bytes([])
        with self.assertRaises(ValueError):
            StakeValidator(0, stake_transaction)
Example #11
0
    def test_validate_tx(self):
        tx = StakeTransaction.create(activation_blocknumber=2,
                                     xmss=self.alice,
                                     slavePK=self.bob.pk(),
                                     hashchain_terminator=sha256(b'T1'))

        # We must sign the tx before validation will work.
        tx.sign(self.alice)

        # We haven't touched the tx: validation should pass
        self.assertTrue(tx.validate_or_raise())
    def test_add_future_sv(self):
        alice_xmss = get_alice_xmss()
        slave_xmss = XMSS(alice_xmss.height, alice_xmss.get_seed())

        stake_validators_tracker = StakeValidatorsTracker.create()

        stake_transaction = StakeTransaction.create(10, alice_xmss, slave_xmss.pk(), b'1111')
        stake_validators_tracker.add_sv(100, stake_transaction, 1)

        total_stake_amount = stake_validators_tracker.get_total_stake_amount()
        self.assertNotEqual(100, total_stake_amount)
Example #13
0
    def _create_stake_tx(self, curr_blocknumber):
        sv_dict = self.buffered_chain.stake_list_get(curr_blocknumber)
        if self.buffered_chain.staking_address in sv_dict:
            activation_blocknumber = sv_dict[
                self.buffered_chain.
                staking_address].activation_blocknumber + config.dev.blocks_per_epoch
        else:
            activation_blocknumber = curr_blocknumber + 2  # Activate as Stake Validator, 2 blocks after current block

        if activation_blocknumber < curr_blocknumber:
            activation_blocknumber = curr_blocknumber + 2

        balance = self.buffered_chain.get_stxn_state(
            curr_blocknumber, self.buffered_chain.staking_address).balance
        if balance < config.dev.minimum_staking_balance_required:
            logger.warning('Staking not allowed due to insufficient balance')
            logger.warning('Balance %s', balance)
            return

        slave_xmss = self.buffered_chain.get_slave_xmss(activation_blocknumber)
        if not slave_xmss:
            return

        signing_xmss = self.buffered_chain.wallet.address_bundle[0].xmss

        st = StakeTransaction.create(
            activation_blocknumber=activation_blocknumber,
            xmss=signing_xmss,
            slavePK=slave_xmss.pk())

        st.sign(signing_xmss)
        tx_state = self.buffered_chain.get_stxn_state(curr_blocknumber,
                                                      st.txfrom)
        if not (st.validate() and st.validate_extended(tx_state)):
            logger.warning(
                'Create St Txn failed due to validation failure, will retry next block'
            )
            return

        self.p2p_factory.broadcast_st(st)
        for num in range(len(self.buffered_chain.tx_pool.transaction_pool)):
            t = self.buffered_chain.tx_pool.transaction_pool[num]
            if t.subtype == qrl_pb2.Transaction.STAKE and st.hash == t.hash:
                if st.get_message_hash() == t.get_message_hash():
                    return
                self.buffered_chain.tx_pool.remove_tx_from_pool(t)
                break

        self.buffered_chain.tx_pool.add_tx_to_pool(st)
        self.buffered_chain.wallet.save_wallet()
Example #14
0
    def ST(self, data):
        """
        Stake Transaction
        This function processes whenever a Transaction having
        subtype ST is received.
        :return:
        """
        try:
            st = StakeTransaction().json_to_transaction(data)
        except Exception as e:
            logger.error(
                'st rejected - unable to decode serialised data - closing connection'
            )
            logger.exception(e)
            self.transport.loseConnection()
            return

        if not self.factory.master_mr.isRequested(st.get_message_hash(), self):
            return

        if len(
                self.factory.chain.m_blockchain
        ) == 1 and st.epoch > 0:  # catch error for new nodes listening for ST's from later epochs
            return

        for t in self.factory.chain.transaction_pool:
            if st.get_message_hash() == t.get_message_hash():
                return

        tx_state = self.factory.chain.block_chain_buffer.get_stxn_state(
            blocknumber=self.factory.chain.block_chain_buffer.height() + 1,
            addr=st.txfrom)
        if st.validate_tx() and st.state_validate_tx(tx_state=tx_state):
            self.factory.chain.add_tx_to_pool(st)
        else:
            hashes = []
            for item in st.hash:
                hashes.append(bin2hstr(item))

            logger.warning('>>>ST %s invalid state validation failed..',
                           hashes)
            return

        self.factory.register_and_broadcast('ST', st.get_message_hash(),
                                            st.transaction_to_json())
        return
    def test_add_sv(self):
        alice_xmss = get_alice_xmss()
        slave_xmss = XMSS(alice_xmss.height, alice_xmss.get_seed())

        stake_validators_tracker = StakeValidatorsTracker.create()

        stake_transaction = StakeTransaction.create(0, alice_xmss, slave_xmss.pk(), b'1111')
        stake_validators_tracker.add_sv(100, stake_transaction, 1)

        balance = stake_validators_tracker.get_stake_balance(alice_xmss.get_address().encode())
        self.assertEqual(100, balance)

        total_stake_amount = stake_validators_tracker.get_total_stake_amount()
        self.assertEqual(100, total_stake_amount)
        stake_validators_tracker.to_json()
Example #16
0
    def test_create2(self):
        alice_xmss = get_alice_xmss()
        slave_xmss = XMSS(alice_xmss.height, alice_xmss.get_seed())

        h0 = sha256(b'hashchain_seed')
        h1 = sha256(h0)
        h2 = sha256(h1)
        h3 = sha256(h2)

        stake_transaction = StakeTransaction.create(activation_blocknumber=0,
                                                    xmss=alice_xmss,
                                                    slavePK=slave_xmss.pk(),
                                                    hashchain_terminator=h3)

        sv = StakeValidator(100, stake_transaction)
        self.assertTrue(sv.validate_hash(h0, 2))
        self.assertTrue(sv.validate_hash(h2, 0))

        self.assertTrue(sv.validate_hash(h2, 0))
        self.assertTrue(sv.validate_hash(h1, 1))
        self.assertTrue(sv.validate_hash(h0, 2))
Example #17
0
    def test_add_2(self):
        destroy_state()
        with State() as state:
            with set_wallet_dir("test_wallet"):
                chain = Chain(state)
                buffered_chain = BufferedChain(chain)

                alice_xmss = get_alice_xmss()
                slave_xmss = XMSS(alice_xmss.height, alice_xmss.get_seed())
                staking_address = bytes(alice_xmss.get_address().encode())

                h0 = sha256(b'hashchain_seed')
                h1 = sha256(h0)

                with mocked_genesis() as custom_genesis:
                    custom_genesis.genesis_balance.extend([
                        qrl_pb2.GenesisBalance(
                            address=alice_xmss.get_address(),
                            balance=700000000000000)
                    ])

                    res = buffered_chain.add_block(block=custom_genesis)
                    self.assertTrue(res)

                    stake_transaction = StakeTransaction.create(
                        activation_blocknumber=1,
                        xmss=alice_xmss,
                        slavePK=slave_xmss.pk(),
                        hashchain_terminator=h1)
                    vote = Vote.create(
                        addr_from=alice_xmss.get_address().encode(),
                        blocknumber=0,
                        headerhash=custom_genesis.headerhash,
                        xmss=slave_xmss)
                    vote.sign(slave_xmss)
                    buffered_chain.add_vote(vote)
                    vote_metadata = buffered_chain.get_consensus(0)

                    # FIXME: The test needs private access.. This is an API issue
                    stake_transaction._data.nonce = 1

                    stake_transaction.sign(alice_xmss)

                    chain.pstate.stake_validators_tracker.add_sv(
                        balance=700000000000000,
                        stake_txn=stake_transaction,
                        blocknumber=1)
                    sv = chain.pstate.stake_validators_tracker.sv_dict[
                        staking_address]
                    self.assertEqual(0, sv.nonce)

                    tmp_block = Block.create(
                        staking_address=bytes(
                            alice_xmss.get_address().encode()),
                        block_number=1,
                        reveal_hash=h0,
                        prevblock_headerhash=custom_genesis.headerhash,
                        transactions=[stake_transaction],
                        duplicate_transactions=OrderedDict(),
                        vote=vote_metadata,
                        signing_xmss=alice_xmss,
                        nonce=1)

                    res = buffered_chain.add_block(block=tmp_block)
                    self.assertTrue(res)
Example #18
0
    def test_add_4(self):
        destroy_state()
        with State() as state:
            with set_wallet_dir("test_wallet"):
                chain = Chain(state)
                buffered_chain = BufferedChain(chain)

                alice_xmss = get_alice_xmss()
                slave_xmss = XMSS(alice_xmss.height, alice_xmss.get_seed())
                random_xmss1 = get_random_xmss()
                random_xmss2 = get_random_xmss()
                staking_address = bytes(alice_xmss.get_address().encode())

                # FIXME: Replace this with a call to create a hash_chain
                h0 = sha256(b'hashchain_seed')
                h1 = sha256(h0)
                h2 = sha256(h1)
                h3 = sha256(h2)
                h4 = sha256(h3)

                with mocked_genesis() as custom_genesis:
                    custom_genesis.genesis_balance.extend([
                        qrl_pb2.GenesisBalance(
                            address=alice_xmss.get_address(),
                            balance=700000000000000)
                    ])

                    res = buffered_chain.add_block(block=GenesisBlock())
                    self.assertTrue(res)
                    stake_transaction = StakeTransaction.create(
                        activation_blocknumber=1,
                        xmss=alice_xmss,
                        slavePK=slave_xmss.pk(),
                        hashchain_terminator=h4)
                    stake_transaction._data.nonce = 1  # FIXME: The test needs private access.. This is an API issue
                    stake_transaction.sign(alice_xmss)

                    vote = Vote.create(
                        addr_from=alice_xmss.get_address().encode(),
                        blocknumber=0,
                        headerhash=GenesisBlock().headerhash,
                        xmss=slave_xmss)
                    vote.sign(slave_xmss)
                    buffered_chain.add_vote(vote)
                    vote_metadata = buffered_chain.get_consensus(0)

                    chain.pstate.stake_validators_tracker.add_sv(
                        balance=700000000000000,
                        stake_txn=stake_transaction,
                        blocknumber=1)

                    sv = chain.pstate.stake_validators_tracker.sv_dict[
                        staking_address]
                    self.assertEqual(0, sv.nonce)

                    # Token Transaction to create a token for test
                    token_transaction = get_token_transaction(
                        random_xmss1, random_xmss2)
                    token_transaction._data.nonce = 1
                    token_transaction.sign(random_xmss1)

                    # Transfer Token Transaction
                    transfer_token1 = TransferTokenTransaction.create(
                        addr_from=random_xmss1.get_address().encode(),
                        token_txhash=token_transaction.txhash,
                        addr_to=alice_xmss.get_address().encode(),
                        amount=100000000,
                        fee=1,
                        xmss_pk=random_xmss1.pk(),
                        xmss_ots_index=random_xmss1.get_index())
                    transfer_token1._data.nonce = 2
                    transfer_token1.sign(random_xmss1)

                    transfer_token2 = TransferTokenTransaction.create(
                        addr_from=random_xmss2.get_address().encode(),
                        token_txhash=token_transaction.txhash,
                        addr_to=alice_xmss.get_address().encode(),
                        amount=200000000,
                        fee=1,
                        xmss_pk=random_xmss2.pk(),
                        xmss_ots_index=random_xmss2.get_index())
                    transfer_token2._data.nonce = 1
                    transfer_token2.sign(random_xmss2)

                    # Transfer Coin Transaction
                    transfer_transaction = TransferTransaction.create(
                        addr_from=random_xmss1.get_address().encode(),
                        addr_to=random_xmss2.get_address().encode(),
                        amount=10,
                        fee=1,
                        xmss_pk=random_xmss1.pk(),
                        xmss_ots_index=random_xmss1.get_index())
                    transfer_transaction._data.nonce = 3
                    transfer_transaction.sign(random_xmss1)

                    tmp_block1 = Block.create(
                        staking_address=staking_address,
                        block_number=1,
                        reveal_hash=h3,
                        prevblock_headerhash=GenesisBlock().headerhash,
                        transactions=[stake_transaction, token_transaction],
                        duplicate_transactions=OrderedDict(),
                        vote=vote_metadata,
                        signing_xmss=slave_xmss,
                        nonce=1)

                    res = buffered_chain.add_block(block=tmp_block1)
                    self.assertTrue(res)

                    # Need to move forward the time to align with block times
                    with mock.patch('qrl.core.ntp.getTime') as time_mock:
                        time_mock.return_value = tmp_block1.timestamp + config.dev.minimum_minting_delay

                        vote = Vote.create(
                            addr_from=alice_xmss.get_address().encode(),
                            blocknumber=1,
                            headerhash=tmp_block1.headerhash,
                            xmss=slave_xmss)
                        vote.sign(slave_xmss)
                        buffered_chain.add_vote(vote)
                        vote_metadata = buffered_chain.get_consensus(1)

                        tmp_block2 = Block.create(
                            staking_address=staking_address,
                            block_number=2,
                            reveal_hash=h2,
                            prevblock_headerhash=tmp_block1.headerhash,
                            transactions=[
                                transfer_token1, transfer_token2,
                                transfer_transaction
                            ],
                            duplicate_transactions=OrderedDict(),
                            vote=vote_metadata,
                            signing_xmss=slave_xmss,
                            nonce=2)

                    res = buffered_chain.add_block(block=tmp_block2)
                    self.assertTrue(res)

                    # Need to move forward the time to align with block times
                    with mock.patch('qrl.core.ntp.getTime') as time_mock:
                        time_mock.return_value = tmp_block2.timestamp + config.dev.minimum_minting_delay

                        vote = Vote.create(
                            addr_from=alice_xmss.get_address().encode(),
                            blocknumber=2,
                            headerhash=tmp_block2.headerhash,
                            xmss=slave_xmss)
                        vote.sign(slave_xmss)
                        buffered_chain.add_vote(vote)
                        vote_metadata = buffered_chain.get_consensus(2)

                        tmp_block3 = Block.create(
                            staking_address=staking_address,
                            block_number=3,
                            reveal_hash=h1,
                            prevblock_headerhash=tmp_block2.headerhash,
                            transactions=[],
                            duplicate_transactions=OrderedDict(),
                            vote=vote_metadata,
                            signing_xmss=slave_xmss,
                            nonce=3)

                    res = buffered_chain.add_block(block=tmp_block3)
                    self.assertTrue(res)

                    chain = buffered_chain._chain
                    random_xmss1_state = chain.pstate._get_address_state(
                        random_xmss1.get_address().encode())
                    random_xmss2_state = chain.pstate._get_address_state(
                        random_xmss2.get_address().encode())

                    self.assertEqual(
                        random_xmss1_state.tokens[bin2hstr(
                            token_transaction.txhash).encode()], 400000000)
                    self.assertEqual(
                        random_xmss2_state.tokens[bin2hstr(
                            token_transaction.txhash).encode()], 200000000)

                    # Need to move forward the time to align with block times
                    with mock.patch('qrl.core.ntp.getTime') as time_mock:
                        time_mock.return_value = tmp_block3.timestamp + config.dev.minimum_minting_delay

                        vote = Vote.create(
                            addr_from=alice_xmss.get_address().encode(),
                            blocknumber=3,
                            headerhash=tmp_block3.headerhash,
                            xmss=slave_xmss)
                        vote.sign(slave_xmss)
                        buffered_chain.add_vote(vote)
                        vote_metadata = buffered_chain.get_consensus(3)

                        tmp_block4 = Block.create(
                            staking_address=staking_address,
                            block_number=4,
                            reveal_hash=h0,
                            prevblock_headerhash=tmp_block3.headerhash,
                            transactions=[],
                            duplicate_transactions=OrderedDict(),
                            vote=vote_metadata,
                            signing_xmss=slave_xmss,
                            nonce=4)

                    res = buffered_chain.add_block(block=tmp_block4)
                    self.assertTrue(res)

                    token_metadata = buffered_chain.get_token_metadata(
                        token_transaction.txhash)

                    self.assertEqual(token_metadata.token_txhash,
                                     token_transaction.txhash)
                    self.assertEqual(
                        len(token_metadata.transfer_token_tx_hashes), 3)
                    self.assertEqual(
                        token_metadata.transfer_token_tx_hashes[0],
                        token_transaction.txhash)

                    random_xmss1_state = chain.pstate._get_address_state(
                        random_xmss1.get_address().encode())
                    random_xmss2_state = chain.pstate._get_address_state(
                        random_xmss2.get_address().encode())
                    alice_state = chain.pstate._get_address_state(
                        alice_xmss.get_address().encode())

                    self.assertEqual(
                        random_xmss1_state.tokens[bin2hstr(
                            token_transaction.txhash).encode()], 300000000)
                    self.assertEqual(
                        random_xmss2_state.tokens[bin2hstr(
                            token_transaction.txhash).encode()], 0)
                    self.assertEqual(
                        alice_state.tokens[bin2hstr(
                            token_transaction.txhash).encode()], 300000000)
                    self.assertEqual(random_xmss1_state.balance,
                                     config.dev.default_account_balance - 13)
                    self.assertEqual(random_xmss2_state.balance,
                                     config.dev.default_account_balance + 9)
Example #19
0
    def test_add_3(self):
        destroy_state()
        with State() as state:
            with set_wallet_dir("test_wallet"):
                chain = Chain(state)
                buffered_chain = BufferedChain(chain)

                alice_xmss = get_alice_xmss()
                slave_xmss = XMSS(alice_xmss.height, alice_xmss.get_seed())

                staking_address = bytes(alice_xmss.get_address().encode())

                # FIXME: Replace this with a call to create a hash_chain
                h0 = sha256(b'hashchain_seed')
                h1 = sha256(h0)
                h2 = sha256(h1)
                h3 = sha256(h2)

                with mocked_genesis() as custom_genesis:
                    custom_genesis.genesis_balance.extend([
                        qrl_pb2.GenesisBalance(
                            address=alice_xmss.get_address(),
                            balance=700000000000000)
                    ])

                    res = buffered_chain.add_block(block=GenesisBlock())
                    self.assertTrue(res)
                    stake_transaction = StakeTransaction.create(
                        activation_blocknumber=1,
                        xmss=alice_xmss,
                        slavePK=slave_xmss.pk(),
                        hashchain_terminator=h3)
                    stake_transaction._data.nonce = 1  # FIXME: The test needs private access.. This is an API issue
                    stake_transaction.sign(alice_xmss)

                    vote = Vote.create(
                        addr_from=alice_xmss.get_address().encode(),
                        blocknumber=0,
                        headerhash=GenesisBlock().headerhash,
                        xmss=slave_xmss)
                    vote.sign(slave_xmss)
                    buffered_chain.add_vote(vote)
                    vote_metadata = buffered_chain.get_consensus(0)

                    chain.pstate.stake_validators_tracker.add_sv(
                        balance=700000000000000,
                        stake_txn=stake_transaction,
                        blocknumber=1)

                    sv = chain.pstate.stake_validators_tracker.sv_dict[
                        staking_address]
                    self.assertEqual(0, sv.nonce)

                    tmp_block1 = Block.create(
                        staking_address=staking_address,
                        block_number=1,
                        reveal_hash=h2,
                        prevblock_headerhash=GenesisBlock().headerhash,
                        transactions=[stake_transaction],
                        duplicate_transactions=OrderedDict(),
                        vote=vote_metadata,
                        signing_xmss=slave_xmss,
                        nonce=1)

                    res = buffered_chain.add_block(block=tmp_block1)
                    self.assertTrue(res)

                    # Need to move forward the time to align with block times
                    with mock.patch('qrl.core.ntp.getTime') as time_mock:
                        time_mock.return_value = tmp_block1.timestamp + config.dev.minimum_minting_delay

                        vote = Vote.create(
                            addr_from=alice_xmss.get_address().encode(),
                            blocknumber=1,
                            headerhash=tmp_block1.headerhash,
                            xmss=slave_xmss)
                        vote.sign(slave_xmss)
                        buffered_chain.add_vote(vote)
                        vote_metadata = buffered_chain.get_consensus(1)

                        tmp_block2 = Block.create(
                            staking_address=staking_address,
                            block_number=2,
                            reveal_hash=h1,
                            prevblock_headerhash=tmp_block1.headerhash,
                            transactions=[],
                            duplicate_transactions=OrderedDict(),
                            vote=vote_metadata,
                            signing_xmss=slave_xmss,
                            nonce=2)

                    res = buffered_chain.add_block(block=tmp_block2)
                    self.assertTrue(res)

                    # Need to move forward the time to align with block times
                    with mock.patch('qrl.core.ntp.getTime') as time_mock:
                        time_mock.return_value = tmp_block2.timestamp + config.dev.minimum_minting_delay

                        vote = Vote.create(
                            addr_from=alice_xmss.get_address().encode(),
                            blocknumber=2,
                            headerhash=tmp_block2.headerhash,
                            xmss=slave_xmss)
                        vote.sign(slave_xmss)
                        buffered_chain.add_vote(vote)
                        vote_metadata = buffered_chain.get_consensus(2)

                        tmp_block3 = Block.create(
                            staking_address=staking_address,
                            block_number=3,
                            reveal_hash=h0,
                            prevblock_headerhash=tmp_block2.headerhash,
                            transactions=[],
                            duplicate_transactions=OrderedDict(),
                            vote=vote_metadata,
                            signing_xmss=slave_xmss,
                            nonce=3)

                    res = buffered_chain.add_block(block=tmp_block3)
                    self.assertTrue(res)
Example #20
0
 def test_create(self):
     tx = StakeTransaction.create(activation_blocknumber=2,
                                  xmss=self.alice,
                                  slavePK=self.bob.pk(),
                                  hashchain_terminator=sha256(b'T1'))
     self.assertTrue(tx)
Example #21
0
 def broadcast_st(self, st: StakeTransaction):
     logger.info('<<<Transmitting ST: %s', st.activation_blocknumber)
     self.register_and_broadcast('ST', st.get_message_hash(), st.to_json())