예제 #1
0
    def test_create(self, time_mock):
        b = BlockHeader.create(blocknumber=1, prev_headerhash=b'headerhash', prev_timestamp=10,
                               hashedtransactions=b'some_data', fee_reward=1)
        self.assertIsNotNone(b)

        b = BlockHeader.create(blocknumber=1, prev_headerhash=b'headerhash', prev_timestamp=10,
                               hashedtransactions=b'some_data', fee_reward=1)
        self.assertEqual(b.epoch, 0)
예제 #2
0
 def test_init2(self):
     with mock.patch('qrl.core.misc.ntp.getTime') as time_mock:
         time_mock.return_value = 1615270948
         block_header = BlockHeader.create(1, sha256(b'prev'),
                                           time_mock.return_value,
                                           sha256(b'txs'), 10)
         self.assertIsNotNone(block_header)  # just to avoid warnings
예제 #3
0
    def test_GetBlockMiningCompatible(self):
        p2p_factory = Mock(spec=P2PFactory)
        p2p_factory.sync_state = SyncState()
        p2p_factory.num_connections = 23
        p2p_factory.pow = Mock()

        chain_manager = Mock(spec=ChainManager)
        chain_manager.height = 0
        chain_manager.get_last_block = MagicMock(return_value=Block())

        qrlnode = QRLNode(mining_address=b'')
        qrlnode.set_chain_manager(chain_manager)
        qrlnode._p2pfactory = p2p_factory
        qrlnode._pow = p2p_factory.pow

        block_header = BlockHeader.create(blocknumber=10,
                                          prev_headerhash=sha256(b'prevblock'),
                                          prev_timestamp=1234567890,
                                          hashedtransactions=sha256(b'tx1'),
                                          fee_reward=1)

        qrlnode.get_blockheader_and_metadata = MagicMock(
            return_value=[block_header, BlockMetadata()])

        service = MiningAPIService(qrlnode)
        req = qrlmining_pb2.GetBlockMiningCompatibleReq(height=10)

        answer = service.GetBlockMiningCompatible(request=req, context=None)

        self.assertEqual(10, answer.blockheader.block_number)
        self.assertEqual(1, answer.blockheader.reward_fee)
예제 #4
0
    def create(dev_config: DevConfig, block_number: int,
               prev_headerhash: bytes, prev_timestamp: int, transactions: list,
               miner_address: bytes, seed_height: Optional[int],
               seed_hash: Optional[bytes]):

        block = Block()

        # Process transactions
        hashedtransactions = []
        fee_reward = 0

        for tx in transactions:
            fee_reward += tx.fee

        # Prepare coinbase tx
        total_reward_amount = BlockHeader.block_reward_calc(
            block_number, dev_config) + fee_reward
        coinbase_tx = CoinBase.create(dev_config, total_reward_amount,
                                      miner_address, block_number)
        hashedtransactions.append(coinbase_tx.txhash)
        Block._copy_tx_pbdata_into_block(
            block, coinbase_tx)  # copy memory rather than sym link

        for tx in transactions:
            hashedtransactions.append(tx.txhash)
            Block._copy_tx_pbdata_into_block(
                block, tx)  # copy memory rather than sym link

        txs_hash = merkle_tx_hash(
            hashedtransactions)  # FIXME: Find a better name, type changes

        tmp_blockheader = BlockHeader.create(dev_config=dev_config,
                                             blocknumber=block_number,
                                             prev_headerhash=prev_headerhash,
                                             prev_timestamp=prev_timestamp,
                                             hashedtransactions=txs_hash,
                                             fee_reward=fee_reward,
                                             seed_height=seed_height,
                                             seed_hash=seed_hash)

        block.blockheader = tmp_blockheader

        block._data.header.MergeFrom(tmp_blockheader.pbdata)

        block.set_nonces(dev_config, 0, 0)

        return block
예제 #5
0
    def create(block_number: int, prev_block_headerhash: bytes,
               prev_block_timestamp: int, transactions: list,
               miner_address: bytes):

        block = Block()

        # Process transactions
        hashedtransactions = []
        fee_reward = 0

        for tx in transactions:
            fee_reward += tx.fee

        # Prepare coinbase tx
        total_reward_amount = BlockHeader.block_reward_calc(
            block_number) + fee_reward
        coinbase_tx = CoinBase.create(total_reward_amount, miner_address,
                                      block_number)
        hashedtransactions.append(coinbase_tx.txhash)
        block._data.transactions.extend([coinbase_tx.pbdata
                                         ])  # copy memory rather than sym link

        for tx in transactions:
            hashedtransactions.append(tx.txhash)
            block._data.transactions.extend(
                [tx.pbdata])  # copy memory rather than sym link

        txs_hash = merkle_tx_hash(
            hashedtransactions)  # FIXME: Find a better name, type changes

        tmp_blockheader = BlockHeader.create(
            blocknumber=block_number,
            prev_block_headerhash=prev_block_headerhash,
            prev_block_timestamp=prev_block_timestamp,
            hashedtransactions=txs_hash,
            fee_reward=fee_reward)

        block.blockheader = tmp_blockheader

        block._data.header.MergeFrom(tmp_blockheader.pbdata)

        block.set_nonces(0, 0)

        return block
예제 #6
0
 def test_blob(self, time_mock):
     block_header = BlockHeader.create(1, sha256(b'prev'),
                                       time_mock.return_value,
                                       sha256(b'txs'), 10)
     self.assertEquals(
         '00501846b24200c31fca7172a7f701ae50322579cfdf1d7777daab4ce6ead70b76debb2c51a1'
         'c700000000000000000000000000000000002b80aecec05ad5c7c4f2259c8f69e2966a6ce102',
         bin2hstr(block_header.mining_blob))
     self.assertEquals(config.dev.mining_blob_size,
                       len(block_header.mining_blob))
예제 #7
0
    def test_create(self, time_mock):
        b = BlockHeader.create(dev_config=config.dev,
                               blocknumber=1,
                               prev_headerhash=b'headerhash',
                               prev_timestamp=10,
                               hashedtransactions=b'some_data',
                               fee_reward=1,
                               seed_height=0,
                               seed_hash=None)
        self.assertIsNotNone(b)

        b = BlockHeader.create(dev_config=config.dev,
                               blocknumber=1,
                               prev_headerhash=b'headerhash',
                               prev_timestamp=10,
                               hashedtransactions=b'some_data',
                               fee_reward=1,
                               seed_height=0,
                               seed_hash=None)
예제 #8
0
    def test_GetLastBlockHeader(self):
        self.block_header_params["blocknumber"] = 20
        block_header = BlockHeader.create(**self.block_header_params)
        self.chain_manager.height = 200
        self.qrlnode.get_blockheader_and_metadata = MagicMock(
            return_value=[block_header, BlockMetadata()])

        req = qrlmining_pb2.GetLastBlockHeaderReq(height=20)
        answer = self.service.GetLastBlockHeader(request=req, context=None)

        self.assertEqual(180, answer.depth)
        self.assertEqual(200, answer.height)
예제 #9
0
 def test_create_fails_when_prev_timestamp_is_negative(self, time_mock):
     # The only way to get it to fail in this mode is to pass a negative timestamp. Which should never happen IRL.
     time_mock.return_value = 0
     b = BlockHeader.create(config.dev,
                            1,
                            sha256(b'prev'),
                            -10,
                            sha256(b'txs'),
                            10,
                            seed_height=0,
                            seed_hash=None)
     self.assertIsNone(b)
예제 #10
0
    def test_blob(self):
        with mock.patch('qrl.core.misc.ntp.getTime') as time_mock:
            time_mock.return_value = 1615270948

            block_header = BlockHeader.create(1, sha256(b'prev'),
                                              sha256(b'txs'), 10)
            self.assertEquals(
                '74aa496ffe19107faaf418b720fb5b8446ba4b595c178fcf099c99b3dee99860d788c77910a9ed000000'
                '000000000000000000e0d022b37421b81b7bbcf5b497fb89408c05c7d713c5e1e5187b02aa9344cf83bb',
                bin2hstr(block_header.mining_blob))
            self.assertEquals(config.dev.mining_blob_size,
                              len(block_header.mining_blob))
예제 #11
0
파일: Block.py 프로젝트: younesmovic/QRL
    def create(staking_address: bytes, block_number: int, reveal_hash: bytes,
               prevblock_headerhash: bytes, transactions: list,
               duplicate_transactions: OrderedDict, vote: VoteMetadata,
               signing_xmss: XMSS, nonce: int):

        block = Block()
        block._data.transactions.extend([qrl_pb2.Transaction()
                                         ])  # FIXME: Empty for coinbase?

        # Process transactions
        hashedtransactions = []
        fee_reward = 0

        for tx in transactions:
            if tx.subtype == qrl_pb2.Transaction.TRANSFER:
                fee_reward += tx.fee
            hashedtransactions.append(tx.txhash)
            block._data.transactions.extend(
                [tx.pbdata])  # copy memory rather than sym link

        if not hashedtransactions:
            hashedtransactions = [sha256(b'')]

        txs_hash = merkle_tx_hash(
            hashedtransactions)  # FIXME: Find a better name, type changes

        for tx in duplicate_transactions.values(
        ):  # TODO: Add merkle hash for dup txn
            block._data.duplicate_transactions.extend([tx.pbdata])

        for staker in vote.stake_validator_vote:  # TODO: Add merkle hash for vote
            block._data.vote.extend([vote.stake_validator_vote[staker].pbdata])

        tmp_blockheader = BlockHeader.create(
            staking_address=staking_address,
            blocknumber=block_number,
            reveal_hash=reveal_hash,
            prev_blockheaderhash=prevblock_headerhash,
            hashedtransactions=txs_hash,
            fee_reward=fee_reward)

        block._data.header.MergeFrom(tmp_blockheader.pbdata)

        # Prepare coinbase tx
        coinbase_tx = CoinBase.create(tmp_blockheader, signing_xmss)
        coinbase_tx.pbdata.nonce = nonce
        coinbase_tx.sign(signing_xmss)  # Sign after nonce has been set

        # Replace first tx
        block._data.transactions[0].CopyFrom(coinbase_tx.pbdata)

        return block
예제 #12
0
    def test_blob(self):
        with mock.patch('qrl.core.misc.ntp.getTime') as time_mock:
            time_mock.return_value = 1615270948

            block_header = BlockHeader.create(1, sha256(b'prev'),
                                              time_mock.return_value,
                                              sha256(b'txs'), 10)
            self.assertEquals(
                '00501846b24200c31fca7172a7f701ae50322579cfdf1d7777daab4ce6ead70b76debb2c51a1'
                'c70000000000000000000000002b80aecec05ad5c7c4f2259c8f69e2966a6ce102d4609af2cd',
                bin2hstr(block_header.mining_blob))
            self.assertEquals(config.dev.mining_blob_size,
                              len(block_header.mining_blob))
예제 #13
0
    def test_hash(self, time_mock):
        block_header = BlockHeader.create(1, sha256(b'prev'),
                                          time_mock.return_value,
                                          sha256(b'txs'), 10)
        header_hash = block_header.generate_headerhash()

        self.assertEquals(
            'ac021e63df860ea930ea9de05e350d3f74af35341688134f92957f1dac3a62fb',
            bin2hstr(header_hash))

        self.assertEquals(bin2hstr(header_hash),
                          bin2hstr(block_header.headerhash))

        self.assertEquals(32, len(block_header.headerhash))
예제 #14
0
    def setUp(self):
        with mock.patch('qrl.core.misc.ntp.getTime', return_value=1615270948) as time_mock:
            self.block_header = BlockHeader.create(1, sha256(b'prev'), time_mock.return_value, sha256(b'txs'), 10)

        self.fee_reward = 10
        self.coinbase_amount = self.block_header.block_reward + self.fee_reward

        # this variable is for validate_parent_child_relation()
        self.m_parent_block = Mock(
            name='mock Parent Block',
            block_number=self.block_header.block_number - 1,
            headerhash=self.block_header.prev_headerhash,
            timestamp=self.block_header.timestamp - 1
        )
예제 #15
0
파일: Block.py 프로젝트: kprimice/QRL
    def update_mining_address(self, mining_address: bytes):
        self.transactions[0].update_mining_address(mining_address)
        hashedtransactions = []

        for tx in self.transactions:
            hashedtransactions.append(tx.transaction_hash)

        tmp_blockheader = BlockHeader.create(
            blocknumber=self.block_number,
            prev_blockheaderhash=self.prev_headerhash,
            hashedtransactions=merkle_tx_hash(hashedtransactions),
            fee_reward=self.fee_reward)

        self._data.header.MergeFrom(tmp_blockheader.pbdata)
예제 #16
0
    def test_hash(self):
        with mock.patch('qrl.core.misc.ntp.getTime') as time_mock:
            time_mock.return_value = 1615270948

            block_header = BlockHeader.create(1, sha256(b'prev'),
                                              sha256(b'txs'), 10)
            header_hash = block_header.generate_headerhash()

            self.assertEquals(
                '584f898a54269d0651cca3403843d4cdb764e5a31655bf51db39bbf8c4883b01',
                bin2hstr(header_hash))

            self.assertEquals(bin2hstr(header_hash),
                              bin2hstr(block_header.headerhash))

            self.assertEquals(32, len(block_header.headerhash))
예제 #17
0
    def test_hash(self):
        with mock.patch('qrl.core.misc.ntp.getTime') as time_mock:
            time_mock.return_value = 1615270948

            block_header = BlockHeader.create(1, sha256(b'prev'),
                                              time_mock.return_value,
                                              sha256(b'txs'), 10)
            header_hash = block_header.generate_headerhash()

            self.assertEquals(
                'eb2364355673f1d4384008dbc53a19050c6d1aaea01c724943c9a8f5d01fdece',
                bin2hstr(header_hash))

            self.assertEquals(bin2hstr(header_hash),
                              bin2hstr(block_header.headerhash))

            self.assertEquals(32, len(block_header.headerhash))
예제 #18
0
    def test_hash(self):
        with mock.patch('qrl.core.misc.ntp.getTime') as time_mock:
            time_mock.return_value = 1615270948

            block_header = BlockHeader.create(1, sha256(b'prev'),
                                              time_mock.return_value,
                                              sha256(b'txs'), 10)
            header_hash = block_header.generate_headerhash()

            self.assertEquals(
                '81dd8032691331fb9cb6d4b8c3cf82dfec7873eb96789a10076b70da45315a38',
                bin2hstr(header_hash))

            self.assertEquals(bin2hstr(header_hash),
                              bin2hstr(block_header.headerhash))

            self.assertEquals(32, len(block_header.headerhash))
예제 #19
0
    def test_hash_nonce(self, time_mock):
        block_header = BlockHeader.create(1, sha256(b'prev'),
                                          time_mock.return_value,
                                          sha256(b'txs'), 10)

        block_header.set_nonces(100, 0)

        header_hash = block_header.generate_headerhash()

        self.assertEquals(
            'b6f937020f9876f3c6887e7a6759201411ed8826ed9ce4283ffe48e1aa90d692',
            bin2hstr(header_hash))

        self.assertEquals(bin2hstr(header_hash),
                          bin2hstr(block_header.headerhash))

        self.assertEquals(32, len(block_header.headerhash))
예제 #20
0
파일: Block.py 프로젝트: fanff/QRL
    def create(mining_nonce: int,
               block_number: int,
               prevblock_headerhash: bytes,
               transactions: list,
               signing_xmss: XMSS,
               master_address: bytes,
               nonce: int):

        block = Block()
        block._data.transactions.extend([qrl_pb2.Transaction()])  # FIXME: Empty for coinbase?

        # Process transactions
        hashedtransactions = []
        fee_reward = 0

        for tx in transactions:
            fee_reward += tx.fee
            hashedtransactions.append(tx.txhash)
            block._data.transactions.extend([tx.pbdata])  # copy memory rather than sym link

        if not hashedtransactions:
            hashedtransactions = [sha256(b'')]

        txs_hash = merkle_tx_hash(hashedtransactions)           # FIXME: Find a better name, type changes

        tmp_blockheader = BlockHeader.create(blocknumber=block_number,
                                             mining_nonce=mining_nonce,
                                             PK=signing_xmss.pk(),
                                             prev_blockheaderhash=prevblock_headerhash,
                                             hashedtransactions=txs_hash,
                                             fee_reward=fee_reward)

        block._data.header.MergeFrom(tmp_blockheader.pbdata)

        # Prepare coinbase tx
        coinbase_tx = CoinBase.create(tmp_blockheader, signing_xmss, master_address)
        coinbase_tx.pbdata.nonce = nonce
        coinbase_tx.sign(signing_xmss)  # Sign after nonce has been set

        # Replace first tx
        block._data.transactions[0].CopyFrom(coinbase_tx.pbdata)

        return block
예제 #21
0
    def test_hash_nonce(self):
        with mock.patch('qrl.core.misc.ntp.getTime') as time_mock:
            time_mock.return_value = 1615270948

            block_header = BlockHeader.create(1, sha256(b'prev'),
                                              sha256(b'txs'), 10)

            block_header.set_nonces(100, 0)

            header_hash = block_header.generate_headerhash()

            self.assertEquals(
                '28556460d0b3b4830ef3d74fab1cd52bca25ee00d1a6396a7f053d53549f73ba',
                bin2hstr(header_hash))

            self.assertEquals(bin2hstr(header_hash),
                              bin2hstr(block_header.headerhash))

            self.assertEquals(32, len(block_header.headerhash))
예제 #22
0
    def create(block_number: int, prevblock_headerhash: bytes,
               transactions: list, signing_xmss: XMSS, master_address: bytes,
               nonce: int):

        block = Block()
        block._data.transactions.extend([qrl_pb2.Transaction()
                                         ])  # FIXME: Empty for coinbase?

        # Process transactions
        hashedtransactions = []
        fee_reward = 0

        for tx in transactions:
            fee_reward += tx.fee
            hashedtransactions.append(tx.txhash)
            block._data.transactions.extend(
                [tx.pbdata])  # copy memory rather than sym link

        if not hashedtransactions:
            hashedtransactions = [sha256(b'')]

        txs_hash = merkle_tx_hash(
            hashedtransactions)  # FIXME: Find a better name, type changes

        tmp_blockheader = BlockHeader.create(
            blocknumber=block_number,
            PK=signing_xmss.pk,
            prev_blockheaderhash=prevblock_headerhash,
            hashedtransactions=txs_hash,
            fee_reward=fee_reward)

        block._data.header.MergeFrom(tmp_blockheader.pbdata)

        # Prepare coinbase tx
        coinbase_tx = CoinBase.create(tmp_blockheader, signing_xmss,
                                      master_address)
        coinbase_tx.pbdata.nonce = nonce
        coinbase_tx.sign(signing_xmss)  # Sign after nonce has been set

        # Replace first tx
        block._data.transactions[0].CopyFrom(coinbase_tx.pbdata)

        return block
예제 #23
0
    def test_GetBlockMiningCompatible(self):
        block_header = BlockHeader.create(**self.block_header_params)
        self.qrlnode.get_blockheader_and_metadata = MagicMock(
            return_value=[block_header, BlockMetadata()])

        req = qrlmining_pb2.GetBlockMiningCompatibleReq(height=10)
        answer = self.service.GetBlockMiningCompatible(request=req,
                                                       context=None)

        self.assertEqual(10, answer.blockheader.block_number)
        self.assertEqual(1, answer.blockheader.reward_fee)

        # if QRLNode responds with None, None, the GRPC response should be blank too
        self.qrlnode.get_blockheader_and_metadata = MagicMock(
            return_value=[None, None])
        answer = self.service.GetBlockMiningCompatible(request=req,
                                                       context=None)
        self.assertEqual(0, answer.blockheader.block_number)
        self.assertEqual(0, answer.blockheader.reward_fee)
예제 #24
0
    def test_hash_nonce(self):
        with mock.patch('qrl.core.misc.ntp.getTime') as time_mock:
            time_mock.return_value = 1615270948

            block_header = BlockHeader.create(1, sha256(b'prev'),
                                              time_mock.return_value,
                                              sha256(b'txs'), 10)

            block_header.set_nonces(100, 0)

            header_hash = block_header.generate_headerhash()

            self.assertEquals(
                'f48ef2a482b2b85b429979ea1d7014806754b3ff37705c4f61a54f17bca4ccc4',
                bin2hstr(header_hash))

            self.assertEquals(bin2hstr(header_hash),
                              bin2hstr(block_header.headerhash))

            self.assertEquals(32, len(block_header.headerhash))
예제 #25
0
    def test_hash_nonce(self):
        with mock.patch('qrl.core.misc.ntp.getTime') as time_mock:
            time_mock.return_value = 1615270948

            block_header = BlockHeader.create(1, sha256(b'prev'),
                                              time_mock.return_value,
                                              sha256(b'txs'), 10)

            block_header.set_nonces(100, 0)

            header_hash = block_header.generate_headerhash()

            self.assertEquals(
                '8ab90d398ef7d219fb985a15814525b42f597a44478599a4a25b4b0a10697cf2',
                bin2hstr(header_hash))

            self.assertEquals(bin2hstr(header_hash),
                              bin2hstr(block_header.headerhash))

            self.assertEquals(32, len(block_header.headerhash))
    def validate_mining_nonce(self,
                              state: State,
                              blockheader: BlockHeader,
                              enable_logging=False):
        parent_metadata = state.get_block_metadata(
            blockheader.prev_blockheaderhash)
        parent_block = state.get_block(blockheader.prev_blockheaderhash)

        measurement = state.get_measurement(blockheader.timestamp,
                                            blockheader.prev_blockheaderhash,
                                            parent_metadata)
        diff, target = DifficultyTracker.get(
            measurement=measurement,
            parent_difficulty=parent_metadata.block_difficulty)

        if enable_logging:
            logger.debug('-----------------START--------------------')
            logger.debug('Validate #%s', blockheader.block_number)
            logger.debug('block.timestamp %s', blockheader.timestamp)
            logger.debug('parent_block.timestamp %s', parent_block.timestamp)
            logger.debug('parent_block.difficulty %s',
                         UInt256ToString(parent_metadata.block_difficulty))
            logger.debug('diff : %s | target : %s', UInt256ToString(diff),
                         target)
            logger.debug('-------------------END--------------------')

        if not self.verify_input_cached(blockheader.mining_blob, target):
            if enable_logging:
                logger.warning("PoW verification failed")
                qn = Qryptonight()
                tmp_hash = qn.hash(blockheader.mining_blob)
                logger.warning("{}".format(tmp_hash))
                logger.debug('%s', blockheader.to_json())
            return False

        return True
예제 #27
0
 def test_init(self):
     block_header = BlockHeader()
     self.assertIsNotNone(block_header)  # just to avoid warnings
예제 #28
0
 def test_init(self):
     # TODO: Not much going on here..
     block_header = BlockHeader()
     self.assertIsNotNone(block_header)  # just to avoid warnings
예제 #29
0
파일: Block.py 프로젝트: kprimice/QRL
class Block(object):
    def __init__(self, protobuf_block=None):
        self._data = protobuf_block
        if protobuf_block is None:
            self._data = qrl_pb2.Block()

        self.blockheader = BlockHeader(self._data.header)

    @property
    def size(self):
        return self._data.ByteSize()

    @property
    def pbdata(self):
        """
        Returns a protobuf object that contains persistable data representing this object
        :return: A protobuf Block object
        :rtype: qrl_pb2.Block
        """
        return self._data

    @property
    def block_number(self):
        return self.blockheader.block_number

    @property
    def epoch(self):
        return int(self.block_number // config.dev.blocks_per_epoch)

    @property
    def headerhash(self):
        return self.blockheader.headerhash

    @property
    def prev_headerhash(self):
        return self.blockheader.prev_blockheaderhash

    @property
    def transactions(self):
        return self._data.transactions

    @property
    def mining_nonce(self):
        return self.blockheader.mining_nonce

    @property
    def PK(self):
        return self.blockheader.PK

    @property
    def block_reward(self):
        return self.blockheader.block_reward

    @property
    def fee_reward(self):
        return self.blockheader.fee_reward

    @property
    def timestamp(self):
        return self.blockheader.timestamp

    @property
    def mining_blob(self) -> bytes:
        return self.blockheader.mining_blob

    @property
    def mining_nonce_offset(self) -> bytes:
        return self.blockheader.nonce_offset

    @staticmethod
    def from_json(json_data):
        pbdata = qrl_pb2.Block()
        Parse(json_data, pbdata)
        return Block(pbdata)

    def verify_blob(self, blob: bytes) -> bool:
        return self.blockheader.verify_blob(blob)

    def set_nonces(self, mining_nonce, extra_nonce=0):
        self.blockheader.set_nonces(mining_nonce, extra_nonce)

    def to_json(self) -> str:
        # FIXME: Remove once we move completely to protobuf
        return MessageToJson(self._data)

    @staticmethod
    def create(block_number: int, prevblock_headerhash: bytes,
               transactions: list, miner_address: bytes):

        block = Block()

        # Process transactions
        hashedtransactions = []
        fee_reward = 0

        for tx in transactions:
            fee_reward += tx.fee

        # Prepare coinbase tx
        total_reward_amount = BlockHeader.block_reward_calc(
            block_number) + fee_reward
        coinbase_tx = CoinBase.create(total_reward_amount, miner_address,
                                      block_number)
        hashedtransactions.append(coinbase_tx.txhash)
        block._data.transactions.extend([coinbase_tx.pbdata
                                         ])  # copy memory rather than sym link

        for tx in transactions:
            hashedtransactions.append(tx.txhash)
            block._data.transactions.extend(
                [tx.pbdata])  # copy memory rather than sym link

        txs_hash = merkle_tx_hash(
            hashedtransactions)  # FIXME: Find a better name, type changes

        tmp_blockheader = BlockHeader.create(
            blocknumber=block_number,
            prev_blockheaderhash=prevblock_headerhash,
            hashedtransactions=txs_hash,
            fee_reward=fee_reward)

        block._data.header.MergeFrom(tmp_blockheader.pbdata)

        block.set_nonces(0, 0)

        return block

    def update_mining_address(self, mining_address: bytes):
        self.transactions[0].update_mining_address(mining_address)
        hashedtransactions = []

        for tx in self.transactions:
            hashedtransactions.append(tx.transaction_hash)

        tmp_blockheader = BlockHeader.create(
            blocknumber=self.block_number,
            prev_blockheaderhash=self.prev_headerhash,
            hashedtransactions=merkle_tx_hash(hashedtransactions),
            fee_reward=self.fee_reward)

        self._data.header.MergeFrom(tmp_blockheader.pbdata)

    def validate(self) -> bool:
        fee_reward = 0
        for index in range(1, len(self.transactions)):
            fee_reward += self.transactions[index].fee

        if len(self.transactions) == 0:
            return False

        try:
            coinbase_txn = Transaction.from_pbdata(self.transactions[0])
            coinbase_amount = coinbase_txn.amount
        except Exception as e:
            logger.warning('Exception %s', e)
            return False

        return self.blockheader.validate(fee_reward, coinbase_amount)

    def validate_parent_child_relation(self, parent_block) -> bool:
        return self.blockheader.validate_parent_child_relation(parent_block)
예제 #30
0
파일: Block.py 프로젝트: fanff/QRL
class Block(object):
    def __init__(self, protobuf_block=None):
        self._data = protobuf_block
        if protobuf_block is None:
            self._data = qrl_pb2.Block()

        self.blockheader = BlockHeader(self._data.header)

    @property
    def size(self):
        return self._data.ByteSize()

    @property
    def pbdata(self):
        """
        Returns a protobuf object that contains persistable data representing this object
        :return: A protobuf Block object
        :rtype: qrl_pb2.Block
        """
        return self._data

    @property
    def block_number(self):
        return self.blockheader.block_number

    @property
    def epoch(self):
        return int(self.block_number // config.dev.blocks_per_epoch)

    @property
    def headerhash(self):
        return self.blockheader.headerhash

    @property
    def prev_headerhash(self):
        return self.blockheader.prev_blockheaderhash

    @property
    def transactions(self):
        return self._data.transactions

    @property
    def mining_nonce(self):
        return self.blockheader.mining_nonce

    @property
    def PK(self):
        return self.blockheader.PK

    @property
    def block_reward(self):
        return self.blockheader.block_reward

    @property
    def timestamp(self):
        return self.blockheader.timestamp

    @property
    def mining_hash(self):
        return self.blockheader.mining_hash

    @staticmethod
    def from_json(json_data):
        pbdata = qrl_pb2.Block()
        Parse(json_data, pbdata)
        return Block(pbdata)

    def set_mining_nonce(self, mining_nonce):
        self.blockheader.set_mining_nonce(mining_nonce)

    def to_json(self)->str:
        # FIXME: Remove once we move completely to protobuf
        return MessageToJson(self._data)

    @staticmethod
    def create(mining_nonce: int,
               block_number: int,
               prevblock_headerhash: bytes,
               transactions: list,
               signing_xmss: XMSS,
               master_address: bytes,
               nonce: int):

        block = Block()
        block._data.transactions.extend([qrl_pb2.Transaction()])  # FIXME: Empty for coinbase?

        # Process transactions
        hashedtransactions = []
        fee_reward = 0

        for tx in transactions:
            fee_reward += tx.fee
            hashedtransactions.append(tx.txhash)
            block._data.transactions.extend([tx.pbdata])  # copy memory rather than sym link

        if not hashedtransactions:
            hashedtransactions = [sha256(b'')]

        txs_hash = merkle_tx_hash(hashedtransactions)           # FIXME: Find a better name, type changes

        tmp_blockheader = BlockHeader.create(blocknumber=block_number,
                                             mining_nonce=mining_nonce,
                                             PK=signing_xmss.pk(),
                                             prev_blockheaderhash=prevblock_headerhash,
                                             hashedtransactions=txs_hash,
                                             fee_reward=fee_reward)

        block._data.header.MergeFrom(tmp_blockheader.pbdata)

        # Prepare coinbase tx
        coinbase_tx = CoinBase.create(tmp_blockheader, signing_xmss, master_address)
        coinbase_tx.pbdata.nonce = nonce
        coinbase_tx.sign(signing_xmss)  # Sign after nonce has been set

        # Replace first tx
        block._data.transactions[0].CopyFrom(coinbase_tx.pbdata)

        return block

    def validate(self) -> bool:
        fee_reward = 0
        for index in range(1, len(self.transactions)):
            fee_reward += self.transactions[index].fee

        if len(self.transactions) == 0:
            return False

        try:
            coinbase_txn = Transaction.from_pbdata(self.transactions[0])
            coinbase_amount = coinbase_txn.amount
        except Exception as e:
            logger.warning('Exception %s', e)
            return False

        return self.blockheader.validate(fee_reward, coinbase_amount)

    def validate_parent_child_relation(self, parent_block) -> bool:
        return self.blockheader.validate_parent_child_relation(parent_block)

    def add_transaction(self, tx: Transaction):
        # TODO: Verify something basic here?
        self._data.transactions.extend(tx.pbdata)
예제 #31
0
class Block(object):
    def __init__(self, protobuf_block=None):
        self._data = protobuf_block
        if protobuf_block is None:
            self._data = qrl_pb2.Block()

        self.blockheader = BlockHeader(self._data.header)

    @property
    def size(self):
        return self._data.ByteSize()

    @property
    def pbdata(self):
        """
        Returns a protobuf object that contains persistable data representing this object
        :return: A protobuf Block object
        :rtype: qrl_pb2.Block
        """
        return self._data

    @property
    def block_number(self):
        return self.blockheader.block_number

    @property
    def epoch(self):
        return int(self.block_number // config.dev.blocks_per_epoch)

    @property
    def headerhash(self):
        return self.blockheader.headerhash

    @property
    def prev_headerhash(self):
        return self.blockheader.prev_blockheaderhash

    @property
    def transactions(self):
        return self._data.transactions

    @property
    def mining_nonce(self):
        return self.blockheader.mining_nonce

    @property
    def PK(self):
        return self.blockheader.PK

    @property
    def block_reward(self):
        return self.blockheader.block_reward

    @property
    def fee_reward(self):
        return self.blockheader.fee_reward

    @property
    def timestamp(self):
        return self.blockheader.timestamp

    @property
    def mining_blob(self) -> bytes:
        return self.blockheader.mining_blob

    @property
    def mining_nonce_offset(self) -> bytes:
        return self.blockheader.nonce_offset

    @staticmethod
    def from_json(json_data):
        pbdata = qrl_pb2.Block()
        Parse(json_data, pbdata)
        return Block(pbdata)

    def verify_blob(self, blob: bytes) -> bool:
        return self.blockheader.verify_blob(blob)

    def set_mining_nonce(self, mining_nonce):
        self.blockheader.set_mining_nonce(mining_nonce)

    def to_json(self) -> str:
        # FIXME: Remove once we move completely to protobuf
        return MessageToJson(self._data)

    @staticmethod
    def create(block_number: int, prevblock_headerhash: bytes,
               transactions: list, signing_xmss: XMSS, master_address: bytes,
               nonce: int):

        block = Block()
        block._data.transactions.extend([qrl_pb2.Transaction()
                                         ])  # FIXME: Empty for coinbase?

        # Process transactions
        hashedtransactions = []
        fee_reward = 0

        for tx in transactions:
            fee_reward += tx.fee
            hashedtransactions.append(tx.txhash)
            block._data.transactions.extend(
                [tx.pbdata])  # copy memory rather than sym link

        if not hashedtransactions:
            hashedtransactions = [sha256(b'')]

        txs_hash = merkle_tx_hash(
            hashedtransactions)  # FIXME: Find a better name, type changes

        tmp_blockheader = BlockHeader.create(
            blocknumber=block_number,
            PK=signing_xmss.pk,
            prev_blockheaderhash=prevblock_headerhash,
            hashedtransactions=txs_hash,
            fee_reward=fee_reward)

        block._data.header.MergeFrom(tmp_blockheader.pbdata)

        # Prepare coinbase tx
        coinbase_tx = CoinBase.create(tmp_blockheader, signing_xmss,
                                      master_address)
        coinbase_tx.pbdata.nonce = nonce
        coinbase_tx.sign(signing_xmss)  # Sign after nonce has been set

        # Replace first tx
        block._data.transactions[0].CopyFrom(coinbase_tx.pbdata)

        return block

    def validate(self) -> bool:
        fee_reward = 0
        for index in range(1, len(self.transactions)):
            fee_reward += self.transactions[index].fee

        if len(self.transactions) == 0:
            return False

        try:
            coinbase_txn = Transaction.from_pbdata(self.transactions[0])
            coinbase_amount = coinbase_txn.amount
        except Exception as e:
            logger.warning('Exception %s', e)
            return False

        return self.blockheader.validate(fee_reward, coinbase_amount)

    def validate_parent_child_relation(self, parent_block) -> bool:
        return self.blockheader.validate_parent_child_relation(parent_block)

    def add_transaction(self, tx: Transaction):
        # TODO: Verify something basic here?
        self._data.transactions.extend(tx.pbdata)
예제 #32
0
    def __init__(self, protobuf_block=None):
        self._data = protobuf_block
        if protobuf_block is None:
            self._data = qrl_pb2.Block()

        self.blockheader = BlockHeader(self._data.header)
예제 #33
0
파일: Block.py 프로젝트: fanff/QRL
    def __init__(self, protobuf_block=None):
        self._data = protobuf_block
        if protobuf_block is None:
            self._data = qrl_pb2.Block()

        self.blockheader = BlockHeader(self._data.header)