Adds the ``vm_class`` to the chain's ``vm_configuration``.

    .. code-block:: python

        from eth.chains.base import MiningChain
        from eth.tools.builder.chain import build, fork_at

        FrontierOnlyChain = build(MiningChain, fork_at(FrontierVM, 0))

        # these two classes are functionally equivalent.
        class FrontierOnlyChain(MiningChain):
            vm_configuration = (
                (0, FrontierVM),
            )

    .. note:: This function is curriable.

    The following pre-curried versions of this function are available as well,
    one for each mainnet fork.

    * :func:`~eth.tools.builder.chain.frontier_at`
    * :func:`~eth.tools.builder.chain.homestead_at`
    * :func:`~eth.tools.builder.chain.tangerine_whistle_at`
    * :func:`~eth.tools.builder.chain.spurious_dragon_at`
    * :func:`~eth.tools.builder.chain.byzantium_at`
    * :func:`~eth.tools.builder.chain.constantinople_at`

def fork_at(vm_class: Type[BaseVM], at_block: int, chain_class: Type[BaseChain]) -> Type[BaseChain]:
    """
    Adds the ``vm_class`` to the chain's ``vm_configuration``.

    .. code-block:: python

        from eth.chains.base import MiningChain
        from eth.tools.builder.chain import build, fork_at

        FrontierOnlyChain = build(MiningChain, fork_at(FrontierVM, 0))

        # these two classes are functionally equivalent.
        class FrontierOnlyChain(MiningChain):
            vm_configuration = (
                (0, FrontierVM),
            )

    .. note:: This function is curriable.

    The following pre-curried versions of this function are available as well,
    one for each mainnet fork.

    * :func:`~eth.tools.builder.chain.frontier_at`
    * :func:`~eth.tools.builder.chain.homestead_at`
    * :func:`~eth.tools.builder.chain.tangerine_whistle_at`
    * :func:`~eth.tools.builder.chain.spurious_dragon_at`
    * :func:`~eth.tools.builder.chain.byzantium_at`
    * :func:`~eth.tools.builder.chain.constantinople_at`
    """
    if chain_class.vm_configuration is not None:
        base_configuration = chain_class.vm_configuration
    else:
        base_configuration = tuple()

    vm_configuration = base_configuration + ((at_block, vm_class),)
    validate_vm_configuration(vm_configuration)
    return chain_class.configure(vm_configuration=vm_configuration)