Ejemplo n.º 1
0
    async def new_peak(self, new_peak: Optional[BlockRecord]) -> List[Tuple[SpendBundle, CostResult, bytes32]]:
        """
        Called when a new peak is available, we try to recreate a mempool for the new tip.
        """
        if new_peak is None:
            return []
        if self.peak == new_peak:
            return []
        if new_peak.height <= self.constants.INITIAL_FREEZE_PERIOD:
            return []

        self.peak = new_peak

        old_pool = self.mempool
        self.mempool = Mempool.create(self.mempool_size)

        for item in old_pool.spends.values():
            await self.add_spendbundle(item.spend_bundle, item.cost_result, item.spend_bundle_name, False)

        potential_txs_copy = self.potential_txs.copy()
        self.potential_txs = {}
        txs_added = []
        for tx, cached_result, cached_name in potential_txs_copy.values():
            cost, status, error = await self.add_spendbundle(tx, cached_result, cached_name)
            if status == MempoolInclusionStatus.SUCCESS:
                txs_added.append((tx, cached_result, cached_name))
        log.debug(
            f"Size of mempool: {len(self.mempool.spends)}, minimum fee to get in: {self.mempool.get_min_fee_rate()}"
        )
        return txs_added
Ejemplo n.º 2
0
    def __init__(self, coin_store: CoinStore,
                 consensus_constants: ConsensusConstants):
        self.constants: ConsensusConstants = consensus_constants
        self.constants_json = recurse_jsonify(
            dataclasses.asdict(self.constants))

        # Transactions that were unable to enter mempool, used for retry. (they were invalid)
        self.potential_txs: Dict[bytes32, Tuple[SpendBundle, CostResult,
                                                bytes32]] = {}
        # Keep track of seen spend_bundles
        self.seen_bundle_hashes: Dict[bytes32, bytes32] = {}

        self.coin_store = coin_store

        tx_per_sec = self.constants.TX_PER_SEC
        sec_per_block = self.constants.SUB_SLOT_TIME_TARGET // self.constants.SLOT_BLOCKS_TARGET
        block_buffer_count = self.constants.MEMPOOL_BLOCK_BUFFER

        # MEMPOOL_SIZE = 60000
        self.mempool_size = int(tx_per_sec * sec_per_block *
                                block_buffer_count)
        self.potential_cache_size = 300
        self.seen_cache_size = 10000
        self.pool = ProcessPoolExecutor(max_workers=1)

        # The mempool will correspond to a certain peak
        self.peak: Optional[BlockRecord] = None
        self.mempool: Mempool = Mempool.create(self.mempool_size)
Ejemplo n.º 3
0
    async def new_peak(self, new_peak: Optional[BlockRecord]):
        """
        Called when a new peak is available, we try to recreate a mempool for the new tip.
        """
        if new_peak is None:
            return
        if self.peak == new_peak:
            return
        if new_peak.height <= self.constants.INITIAL_FREEZE_PERIOD:
            return

        self.peak = new_peak

        old_pool = self.mempool
        self.mempool = Mempool.create(self.mempool_size)

        for item in old_pool.spends.values():
            await self.add_spendbundle(item.spend_bundle, item.cost_result,
                                       item.spend_bundle_name, False)

        potential_txs_copy = self.potential_txs.copy()
        self.potential_txs = {}
        for tx, cached_result, cached_name in potential_txs_copy.values():
            await self.add_spendbundle(tx, cached_result, cached_name)
        log.debug(
            f"Size of mempool: {len(self.mempool.spends)}, minimum fee to get in: {self.mempool.get_min_fee_rate()}"
        )
Ejemplo n.º 4
0
    def __init__(self, coin_store: CoinStore,
                 consensus_constants: ConsensusConstants):
        self.constants: ConsensusConstants = consensus_constants

        # Transactions that were unable to enter mempool, used for retry. (they were invalid)
        self.potential_txs: Dict[bytes32, Tuple[SpendBundle, CostResult]] = {}
        # Keep track of seen spend_bundles
        self.seen_bundle_hashes: Dict[bytes32, bytes32] = {}

        # old_mempools will contain transactions that were removed in the last 10 blocks
        self.old_mempools: SortedDict[uint32,
                                      Dict[bytes32,
                                           MempoolItem]] = SortedDict()  # pylint: disable=E1136
        self.coin_store = coin_store

        tx_per_sec = self.constants.TX_PER_SEC
        sec_per_block = self.constants.SUB_SLOT_TIME_TARGET // self.constants.SLOT_SUB_BLOCKS_TARGET
        block_buffer_count = self.constants.MEMPOOL_BLOCK_BUFFER

        # MEMPOOL_SIZE = 60000
        self.mempool_size = int(tx_per_sec * sec_per_block *
                                block_buffer_count)
        self.potential_cache_size = 300
        self.seen_cache_size = 10000

        # The mempool will correspond to a certain peak
        self.peak: Optional[SubBlockRecord] = None
        self.mempool: Mempool = Mempool.create(self.mempool_size)
    async def new_tips(self, new_tips: List[FullBlock]):
        """
        Called when new tips are available, we try to recreate a mempool for each of the new tips.
        For tip that we already have mempool we don't do anything.
        """
        new_pools: Dict[bytes32, Mempool] = {}

        min_mempool_height = sys.maxsize
        for pool in self.mempools.values():
            if pool.header.height < min_mempool_height:
                min_mempool_height = pool.header.height

        for tip in new_tips:
            if tip.header_hash in self.mempools:
                # Nothing to change, we already have mempool for this head
                new_pools[tip.header_hash] = self.mempools[tip.header_hash]
                continue

            new_pool = Mempool.create(tip.header, self.mempool_size)
            if tip.height < min_mempool_height:
                # Update old mempool
                if len(self.old_mempools) > 0:
                    log.info(f"Creating new pool: {new_pool.header}")

                    # If old spends height is bigger than the new tip height, try adding spends to the pool
                    for height in self.old_mempools.keys():
                        old_spend_dict: Dict[bytes32, MempoolItem] = self.old_mempools[
                            height
                        ]
                        await self.add_old_spends_to_pool(new_pool, old_spend_dict)

            await self.initialize_pool_from_current_pools(new_pool)
            await self.add_potential_spends_to_pool(new_pool)
            new_pools[new_pool.header.header_hash] = new_pool

        for pool in self.mempools.values():
            if pool.header.header_hash not in new_pools:
                await self.add_to_old_mempool_cache(
                    list(pool.spends.values()), pool.header
                )

        self.mempools = new_pools
Ejemplo n.º 6
0
    async def new_peak(self, new_peak: Optional[SubBlockRecord]):
        """
        Called when a new peak is available, we try to recreate a mempool for the new tip.
        """
        if new_peak is None:
            return
        if self.peak == new_peak:
            return
        self.peak = new_peak

        old_pool = self.mempool
        self.mempool = Mempool.create(self.mempool_size)

        for item in old_pool.spends.values():
            await self.add_spendbundle(item.spend_bundle, item.cost_result)

        self.potential_txs_copy = self.potential_txs.copy()
        self.potential_txs = {}
        for tx, cached_result in self.potential_txs_copy.values():
            await self.add_spendbundle(tx, cached_result)