예제 #1
0
    def test_regular_block_template(self):
        manager = self.create_peer('testnet', tx_storage=self.tx_storage)

        # add 100 blocks
        blocks = add_new_blocks(manager, 100, advance_clock=15)

        block_templates = manager.get_block_templates()
        self.assertEqual(len(block_templates), 1)
        self.assertEqual(
            block_templates[0],
            BlockTemplate(
                versions={0, 3},
                reward=settings.INITIAL_TOKEN_UNITS_PER_BLOCK * 100,
                weight=1.0,
                timestamp_now=int(manager.reactor.seconds()),
                timestamp_min=blocks[-1].timestamp + 1,
                timestamp_max=blocks[-1].timestamp +
                settings.MAX_DISTANCE_BETWEEN_BLOCKS - 1,
                # parents=[blocks[-1].hash, self.genesis_txs[-1].hash, self.genesis_txs[-2].hash],
                parents=block_templates[0].parents,
                parents_any=[],
                height=101,  # genesis is 0
                score=sum_weights(blocks[-1].get_metadata().score, 1.0),
            ))

        self.assertConsensusValid(manager)
예제 #2
0
 def _handle_request(self, data: Dict) -> None:
     # only request accepted is a 'mining.notify' notification
     if data['method'] != 'mining.notify':
         self.log.warn('unknown method received', data=data)
         return
     block_templates = BlockTemplates(BlockTemplate.from_dict(d) for d in data.get('params', []))
     if self._queue.done():
         self._queue = self.loop.create_future()
     self._queue.set_result(block_templates)
예제 #3
0
 async def submit(self, block: Block) -> Optional[BlockTemplate]:
     resp: Union[bool, Dict] = await self._do_request('mining.submit', {
         'hexdata': bytes(block).hex(),
     })
     if resp:
         assert isinstance(resp, Dict)
         error = resp.get('error')
         if error:
             raise APIError(error)
         return BlockTemplate.from_dict(resp['result'])
     return None
예제 #4
0
    def test_block_template_after_genesis(self):
        manager = self.create_peer('testnet', tx_storage=self.tx_storage)

        block_templates = manager.get_block_templates()
        self.assertEqual(len(block_templates), 1)
        self.assertEqual(block_templates[0], BlockTemplate(
            versions={0, 3},
            reward=settings.INITIAL_TOKEN_UNITS_PER_BLOCK * 100,
            weight=1.0,
            timestamp_now=int(manager.reactor.seconds()),
            timestamp_min=settings.GENESIS_TIMESTAMP + 3,
            timestamp_max=0xffffffff,  # no limit for next block after genesis
            # parents=[tx.hash for tx in self.genesis_blocks + self.genesis_txs],
            parents=block_templates[0].parents,
            parents_any=[],
            height=1,  # genesis is 0
            score=sum_weights(self.genesis_blocks[0].weight, 1.0),
        ))
예제 #5
0
 def _make_block_template(self,
                          parent_block: Block,
                          parent_txs: 'ParentTxs',
                          current_timestamp: int,
                          with_weight_decay: bool = False) -> BlockTemplate:
     """ Further implementation of making block template, used by make_block_template and make_custom_block_template
     """
     assert parent_block.hash is not None
     # the absolute minimum would be the previous timestamp + 1
     timestamp_abs_min = parent_block.timestamp + 1
     # and absolute maximum limited by max time between blocks
     if not parent_block.is_genesis:
         timestamp_abs_max = parent_block.timestamp + settings.MAX_DISTANCE_BETWEEN_BLOCKS - 1
     else:
         timestamp_abs_max = 0xffffffff
     assert timestamp_abs_max > timestamp_abs_min
     # actual minimum depends on the timestamps of the parent txs
     # it has to be at least the max timestamp of parents + 1
     timestamp_min = max(timestamp_abs_min, parent_txs.max_timestamp + 1)
     assert timestamp_min <= timestamp_abs_max
     # when we have weight decay, the max timestamp will be when the next decay happens
     if with_weight_decay and settings.WEIGHT_DECAY_ENABLED:
         # we either have passed the first decay or not, the range will vary depending on that
         if timestamp_min > timestamp_abs_min + settings.WEIGHT_DECAY_ACTIVATE_DISTANCE:
             timestamp_max_decay = timestamp_min + settings.WEIGHT_DECAY_WINDOW_SIZE
         else:
             timestamp_max_decay = timestamp_abs_min + settings.WEIGHT_DECAY_ACTIVATE_DISTANCE
         timestamp_max = min(timestamp_abs_max, timestamp_max_decay)
     else:
         timestamp_max = timestamp_abs_max
     timestamp = min(max(current_timestamp, timestamp_min), timestamp_max)
     weight = daa.calculate_next_weight(parent_block, timestamp)
     parent_block_metadata = parent_block.get_metadata()
     height = parent_block_metadata.height + 1
     parents = [parent_block.hash] + parent_txs.must_include
     parents_any = parent_txs.can_include
     # simplify representation when you only have one to choose from
     if len(parents) + len(parents_any) == 3:
         parents.extend(sorted(parents_any))
         parents_any = []
     assert len(parents) + len(
         parents_any) >= 3, 'There should be enough parents to choose from'
     assert 1 <= len(parents) <= 3, 'Impossible number of parents'
     if __debug__ and len(parents) == 3:
         assert len(
             parents_any
         ) == 0, 'Extra parents to choose from that cannot be chosen'
     return BlockTemplate(
         versions={
             TxVersion.REGULAR_BLOCK.value,
             TxVersion.MERGE_MINED_BLOCK.value
         },
         reward=daa.get_tokens_issued_per_block(height),
         weight=weight,
         timestamp_now=current_timestamp,
         timestamp_min=timestamp_min,
         timestamp_max=timestamp_max,
         parents=parents,
         parents_any=parents_any,
         height=height,
         score=sum_weights(parent_block_metadata.score, weight),
     )