Skip to content

Recent History (β)

Bases: StateComponent

Source code in pyjamaz/state/components.py
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
class RecentHistory(StateComponent):
    component_id = 3

    @log_execution_time
    def state_transition_intermediate(
            self,
            header: Header,
            pre_state_recent_history: RecentHistoryState
    ) -> RecentHistoryIntermediateOutput:
        """
        GP-0.7.2-eq:7.5 (β†_H) | Intermediate state transition function for the state's recent history.

        Parameters
        ----------
        header: Header
            GP-0.7.2-eq:4.6 (bold_H)
        pre_state_recent_history: RecentHistoryState
            GP-0.7.2-eq:4.6 (β_H)

        Returns
        -------
        RecentHistoryIntermediateOutput
            Output containing: Intermediate state of RecentHistoryState (β†)
        """
        intermediate_state_recent_history = deepcopy(pre_state_recent_history)

        if len(pre_state_recent_history.recent_blocks) > 0:
            intermediate_state_recent_history.recent_blocks[-1].state_root = header.parent_state_root

        # return intermediate_state_recent_history
        return RecentHistoryIntermediateOutput(
            intermediate_state=intermediate_state_recent_history
        )

    @log_execution_time
    def state_transition(
            self,
            header: Header,
            extrinsic_guarantees: List[Guarantee],
            intermediate_state_recent_history: RecentHistoryState,
            beefy_commitment_map: Union[BeefyCommitmentMap, bytes]
    ) -> RecentHistoryOutput:
        """
        GP-0.7.2-eq:7.6,7.7,7.8 (β'B, β'H) | State transition function for the state's recent history.

        Parameters
        ----------
        header: Header
            GP-0.7.2-eq:4.17 (bold_H)
        extrinsic_guarantees: List[Guarantee]
            GP-0.7.2-eq:4.17 (bold_E_G)
        intermediate_state_recent_history: RecentHistoryState
            GP-0.7.2-eq:4.17 (β†_H)
        beefy_commitment_map: Union[BeefyCommitmentMap, bytes]
            GP-0.7.2-eq:4.17 (bold_C)

        Returns
        -------
        RecentHistoryOutput
            Output containing: Posterior state of RecentHistoryState (β')
        """
        # TODO: Does bold_C need to be replaced by θ? Unclear
        post_state_recent_history = deepcopy(intermediate_state_recent_history)

        reported_work_packages = sorted([
            ReportedWorkPackage(
                hash=g.report.package_spec.hash,
                exports_root=g.report.package_spec.exports_root
            ) for g in extrinsic_guarantees
        ], key=lambda g: g.hash)

        # No more work reports than number of cores GP-0.7.2-eq:7.2
        # TODO: implicit limit to work-reports. GP-0.7.0 has a model change making bold_p a dictionary.
        if len(reported_work_packages) > gp_const.CORE_COUNT:
            raise StateTransitionError(f"Work reports must be less than number of cores ({gp_const.CORE_COUNT})")

        if len(intermediate_state_recent_history.recent_blocks) > 0:
            mmr_peaks = intermediate_state_recent_history.accumulation_output_log
        else:
            mmr_peaks = []

        # Extend MMR
        if type(beefy_commitment_map) is bytes:
            accumulate_root = beefy_commitment_map
        else:
            accumulate_root = beefy_commitment_map.get_accumulate_root()

        DEBUG and logging.debug(f'accumulate_root={format_hash(accumulate_root)}')

        mmr = MerkleMountainRange(mmr_peaks)
        mmr.insert(accumulate_root)

        post_state_recent_history.accumulation_output_log = mmr.peaks

        recent_block = RecentBlock(
            header_hash=header.hash,
            beefy_root=mmr.super_peak(),
            state_root=bytes(32),
            reported=reported_work_packages
        )
        DEBUG and logging.debug(f"beefy_root={format_hash(recent_block.beefy_root)}")

        post_state_recent_history.recent_blocks.append(recent_block)

        if len(post_state_recent_history.recent_blocks) > gp_const.HISTORY:
            # Limit reached, delete first (oldest) item in block history
            post_state_recent_history.recent_blocks.pop(0)

        return RecentHistoryOutput(
            post_state=post_state_recent_history
        )

    def retrieve_state(self) -> RecentHistoryState:
        value = self.retrieve()
        return RecentHistoryState.from_jam_bytes(JamBytes(value))

state_transition_intermediate(header: Header, pre_state_recent_history: RecentHistoryState) -> RecentHistoryIntermediateOutput

GP-0.7.2-eq:7.5 (β†_H) | Intermediate state transition function for the state's recent history.

Parameters:

Name Type Description Default
header Header

GP-0.7.2-eq:4.6 (bold_H)

required
pre_state_recent_history RecentHistoryState

GP-0.7.2-eq:4.6 (β_H)

required

Returns:

Type Description
RecentHistoryIntermediateOutput

Output containing: Intermediate state of RecentHistoryState (β†)

Source code in pyjamaz/state/components.py
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
@log_execution_time
def state_transition_intermediate(
        self,
        header: Header,
        pre_state_recent_history: RecentHistoryState
) -> RecentHistoryIntermediateOutput:
    """
    GP-0.7.2-eq:7.5 (β†_H) | Intermediate state transition function for the state's recent history.

    Parameters
    ----------
    header: Header
        GP-0.7.2-eq:4.6 (bold_H)
    pre_state_recent_history: RecentHistoryState
        GP-0.7.2-eq:4.6 (β_H)

    Returns
    -------
    RecentHistoryIntermediateOutput
        Output containing: Intermediate state of RecentHistoryState (β†)
    """
    intermediate_state_recent_history = deepcopy(pre_state_recent_history)

    if len(pre_state_recent_history.recent_blocks) > 0:
        intermediate_state_recent_history.recent_blocks[-1].state_root = header.parent_state_root

    # return intermediate_state_recent_history
    return RecentHistoryIntermediateOutput(
        intermediate_state=intermediate_state_recent_history
    )

state_transition(header: Header, extrinsic_guarantees: List[Guarantee], intermediate_state_recent_history: RecentHistoryState, beefy_commitment_map: Union[BeefyCommitmentMap, bytes]) -> RecentHistoryOutput

GP-0.7.2-eq:7.6,7.7,7.8 (β'B, β'H) | State transition function for the state's recent history.

Parameters:

Name Type Description Default
header Header

GP-0.7.2-eq:4.17 (bold_H)

required
extrinsic_guarantees List[Guarantee]

GP-0.7.2-eq:4.17 (bold_E_G)

required
intermediate_state_recent_history RecentHistoryState

GP-0.7.2-eq:4.17 (β†_H)

required
beefy_commitment_map Union[BeefyCommitmentMap, bytes]

GP-0.7.2-eq:4.17 (bold_C)

required

Returns:

Type Description
RecentHistoryOutput

Output containing: Posterior state of RecentHistoryState (β')

Source code in pyjamaz/state/components.py
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
@log_execution_time
def state_transition(
        self,
        header: Header,
        extrinsic_guarantees: List[Guarantee],
        intermediate_state_recent_history: RecentHistoryState,
        beefy_commitment_map: Union[BeefyCommitmentMap, bytes]
) -> RecentHistoryOutput:
    """
    GP-0.7.2-eq:7.6,7.7,7.8 (β'B, β'H) | State transition function for the state's recent history.

    Parameters
    ----------
    header: Header
        GP-0.7.2-eq:4.17 (bold_H)
    extrinsic_guarantees: List[Guarantee]
        GP-0.7.2-eq:4.17 (bold_E_G)
    intermediate_state_recent_history: RecentHistoryState
        GP-0.7.2-eq:4.17 (β†_H)
    beefy_commitment_map: Union[BeefyCommitmentMap, bytes]
        GP-0.7.2-eq:4.17 (bold_C)

    Returns
    -------
    RecentHistoryOutput
        Output containing: Posterior state of RecentHistoryState (β')
    """
    # TODO: Does bold_C need to be replaced by θ? Unclear
    post_state_recent_history = deepcopy(intermediate_state_recent_history)

    reported_work_packages = sorted([
        ReportedWorkPackage(
            hash=g.report.package_spec.hash,
            exports_root=g.report.package_spec.exports_root
        ) for g in extrinsic_guarantees
    ], key=lambda g: g.hash)

    # No more work reports than number of cores GP-0.7.2-eq:7.2
    # TODO: implicit limit to work-reports. GP-0.7.0 has a model change making bold_p a dictionary.
    if len(reported_work_packages) > gp_const.CORE_COUNT:
        raise StateTransitionError(f"Work reports must be less than number of cores ({gp_const.CORE_COUNT})")

    if len(intermediate_state_recent_history.recent_blocks) > 0:
        mmr_peaks = intermediate_state_recent_history.accumulation_output_log
    else:
        mmr_peaks = []

    # Extend MMR
    if type(beefy_commitment_map) is bytes:
        accumulate_root = beefy_commitment_map
    else:
        accumulate_root = beefy_commitment_map.get_accumulate_root()

    DEBUG and logging.debug(f'accumulate_root={format_hash(accumulate_root)}')

    mmr = MerkleMountainRange(mmr_peaks)
    mmr.insert(accumulate_root)

    post_state_recent_history.accumulation_output_log = mmr.peaks

    recent_block = RecentBlock(
        header_hash=header.hash,
        beefy_root=mmr.super_peak(),
        state_root=bytes(32),
        reported=reported_work_packages
    )
    DEBUG and logging.debug(f"beefy_root={format_hash(recent_block.beefy_root)}")

    post_state_recent_history.recent_blocks.append(recent_block)

    if len(post_state_recent_history.recent_blocks) > gp_const.HISTORY:
        # Limit reached, delete first (oldest) item in block history
        post_state_recent_history.recent_blocks.pop(0)

    return RecentHistoryOutput(
        post_state=post_state_recent_history
    )