def ecpairing(
        computation: BaseComputation,
        gas_cost_base: int = constants.GAS_ECPAIRING_BASE,
        gas_cost_per_point: int = constants.GAS_ECPAIRING_PER_POINT) -> BaseComputation:

    if len(computation.msg.data) % 192:
        # data length must be an exact multiple of 192
        raise VMError("Invalid ECPAIRING parameters")

    num_points = len(computation.msg.data) // 192
    gas_fee = gas_cost_base + num_points * gas_cost_per_point

    computation.consume_gas(gas_fee, reason='ECPAIRING Precompile')

    try:
        result = _ecpairing(computation.msg.data)
    except ValidationError:
        raise VMError("Invalid ECPAIRING parameters")

    if result is True:
        computation.output = pad32(b'\x01')
    elif result is False:
        computation.output = pad32(b'\x00')
    else:
        raise Exception("Invariant: unreachable code path")
    return computation
def test_output_with_vmerror(computation):
    # Trigger an out of gas error causing output to be b''
    computation.output = b'1'
    with computation:
        raise VMError('Triggered VMError for tests')
    assert computation.is_error
    assert computation.output == b''
def test_get_gas_remaining_with_vmerror(computation):
    assert computation.get_gas_remaining() == 100
    # Trigger an out of gas error causing get gas remaining to be 0
    with computation:
        raise VMError('Triggered VMError for tests')
    assert computation.is_error
    assert computation.get_gas_remaining() == 0
def test_get_gas_refund_with_vmerror(computation):
    # Trigger an out of gas error causing get gas refund to be 0
    computation._gas_meter.refund_gas(100)
    with computation:
        raise VMError('Triggered VMError for tests')
    assert computation.is_error
    assert computation.get_gas_refund() == 0
def test_get_log_entries_with_vmerror(computation, canonical_address_a):
    # Trigger an out of gas error causing get log entries to be ()
    computation.add_log_entry(canonical_address_a, [1, 2, 3], b'')
    with computation:
        raise VMError('Triggered VMError for tests')
    assert computation.is_error
    assert computation.get_log_entries() == ()
Exemple #6
0
def test_get_log_entries_with_vmerror(computation):
    # Trigger an out of gas error causing get log entries to be ()
    computation.add_log_entry(CANONICAL_ADDRESS_A, [1, 2, 3], b'')
    with computation:
        raise VMError('Triggered VMError for tests')
    assert computation.is_error
    assert computation.get_log_entries() == ()
def test_should_erase_return_data_with_vm_error(computation):
    assert computation.get_gas_remaining() == 100
    computation.return_data = b'\x1337'
    # Trigger a VMError which should erase the return data
    with computation:
        raise VMError('Triggered VMError for tests')
    assert computation.should_erase_return_data
    assert computation.return_data == b''
def test_should_burn_gas_with_vm_error(computation):
    assert computation.get_gas_remaining() == 100
    # Trigger an out of gas error causing remaining gas to be 0
    with computation:
        raise VMError('Triggered VMError for tests')
    assert computation.should_burn_gas
    assert computation.get_gas_used() == 100
    assert computation.get_gas_remaining() == 0
def test_get_gas_used_with_vmerror(computation):
    # Trigger an out of gas error causing get gas used to be 150
    computation.consume_gas(3, reason='testing')
    computation.consume_gas(2, reason='testing')
    with computation:
        raise VMError('Triggered VMError for tests')
    assert computation.is_error
    assert computation.get_gas_used() == 100
Exemple #10
0
def blake2b_fcompress(computation: BaseComputation) -> BaseComputation:
    try:
        parameters = extract_blake2b_parameters(computation.msg.data_as_bytes)
    except ValidationError as exc:
        raise VMError(
            f"Blake2b input parameter validation failure: {exc}") from exc

    num_rounds = parameters[0]
    gas_cost = GAS_COST_PER_ROUND * num_rounds

    computation.consume_gas(
        gas_cost, reason=f"Blake2b Compress Precompile w/ {num_rounds} rounds")

    computation.output = _do_compression(*parameters)
    return computation
Exemple #11
0
def ecmul(computation: BaseComputation) -> BaseComputation:
    computation.consume_gas(constants.GAS_ECMUL, reason='ECMUL Precompile')

    try:
        result = _ecmull(computation.msg.data)
    except ValidationError:
        raise VMError("Invalid ECMUL parameters")

    result_x, result_y = result
    result_bytes = b''.join((
        pad32(int_to_big_endian(result_x.n)),
        pad32(int_to_big_endian(result_y.n)),
    ))
    computation.output = result_bytes
    return computation
Exemple #12
0
def ecadd(
        computation: BaseComputation,
        gas_cost: int = constants.GAS_ECADD) -> BaseComputation:

    computation.consume_gas(gas_cost, reason='ECADD Precompile')

    try:
        result = _ecadd(computation.msg.data_as_bytes)
    except ValidationError:
        raise VMError("Invalid ECADD parameters")

    result_x, result_y = result
    result_bytes = b''.join((
        pad32(int_to_big_endian(result_x.n)),
        pad32(int_to_big_endian(result_y.n)),
    ))
    computation.output = result_bytes
    return computation
Exemple #13
0
def test_should_erase_return_data_with_vm_error(computation):
    assert computation.get_gas_remaining() == 100
    # Trigger an out of gas error causing get gas remaining to be 0
    with computation:
        raise VMError('Triggered VMError for tests')
    assert computation.should_erase_return_data