A simple strategy for adjusting the gas limit.

    For each block:

    - decrease by 1/1024th of the gas limit from the previous block
    - increase by 50% of the total gas used by the previous block

    If the value is less than the given `gas_limit_floor`:

    - increase the gas limit by 1/1024th of the gas limit from the previous block.

    If the value is less than the GAS_LIMIT_MINIMUM:

    - use the GAS_LIMIT_MINIMUM as the new gas limit.

def compute_gas_limit(parent_header: BlockHeader, gas_limit_floor: int) -> int:
    """
    A simple strategy for adjusting the gas limit.

    For each block:

    - decrease by 1/1024th of the gas limit from the previous block
    - increase by 50% of the total gas used by the previous block

    If the value is less than the given `gas_limit_floor`:

    - increase the gas limit by 1/1024th of the gas limit from the previous block.

    If the value is less than the GAS_LIMIT_MINIMUM:

    - use the GAS_LIMIT_MINIMUM as the new gas limit.
    """
    if gas_limit_floor < GAS_LIMIT_MINIMUM:
        raise ValueError(
            "The `gas_limit_floor` value must be greater than the "
            "GAS_LIMIT_MINIMUM.  Got {0}.  Must be greater than "
            "{1}".format(gas_limit_floor, GAS_LIMIT_MINIMUM)
        )

    decay = parent_header.gas_limit // GAS_LIMIT_EMA_DENOMINATOR

    if parent_header.gas_used:
        usage_increase = (
            parent_header.gas_used * GAS_LIMIT_USAGE_ADJUSTMENT_NUMERATOR
        ) // (
            GAS_LIMIT_USAGE_ADJUSTMENT_DENOMINATOR
        ) // (
            GAS_LIMIT_EMA_DENOMINATOR
        )
    else:
        usage_increase = 0

    gas_limit = max(
        GAS_LIMIT_MINIMUM,
        parent_header.gas_limit - decay + usage_increase
    )

    if gas_limit < GAS_LIMIT_MINIMUM:
        return GAS_LIMIT_MINIMUM
    elif gas_limit < gas_limit_floor:
        return parent_header.gas_limit + decay
    else:
        return gas_limit