[go: nahoru, domu]

Skip to content

Commit

Permalink
Merge pull request NethermindEth#160 from NethermindEth/murcake/optim…
Browse files Browse the repository at this point in the history
…ize-array-load

Murcake/optimize array load
  • Loading branch information
temyurchenko committed Dec 19, 2021
2 parents ceec36a + 1395734 commit 9d66d67
Show file tree
Hide file tree
Showing 46 changed files with 477 additions and 298 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ test: test_bats test_yul benchmark
.PHONY: test

test_bats: warp $(BATS_FILES) tests/cli/*.bats
bats -j $(NPROCS) $^ $(BATS_ARGS)
bats -j $(NPROCS) $^ $(ARGS)
.PHONY: test_bats

test_yul: warp
Expand Down
17 changes: 12 additions & 5 deletions tests/behaviour/calldatacopy_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
from yul.starknet_utils import deploy_contract, invoke_method
from yul.utils import cairoize_bytes

from warp.logging.generateMarkdown import steps_in_function

warp_root = os.path.abspath(os.path.join(__file__, "../../.."))
test_dir = __file__

Expand All @@ -29,8 +27,17 @@ async def test_calldatacopy():
starknet, program_info, contract_definition
)

evm_calldata = get_evm_calldata(program_info["sol_abi"], "callMe", [])
evm_calldata = get_evm_calldata(program_info["sol_abi"], "copyFourBytes", [0])
[first_four_bytes], _ = cairoize_bytes(evm_calldata[:4])
res = await invoke_method(starknet, program_info, contract_address, "callMe")
steps_in_function(sol_file, "callMe", res, "calldatacopy_test")
evm_calldata = get_evm_calldata(program_info["sol_abi"], "copyFourBytes", [4])
[next_four_bytes], _ = cairoize_bytes(evm_calldata[4:8])

res = await invoke_method(
starknet, program_info, contract_address, "copyFourBytes", 0
)
assert res.retdata == [4, 1, first_four_bytes]

res = await invoke_method(
starknet, program_info, contract_address, "copyFourBytes", 4
)
assert res.retdata == [4, 1, next_four_bytes]
13 changes: 11 additions & 2 deletions tests/behaviour/malicious-calldata_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,19 @@ async def test_normal_contract_call(
async def test_malicious_deploy(starknet, friendly_info, friendly_def):
evm_calldata = get_ctor_evm_calldata(friendly_info["sol_abi"], [0])
cairo_calldata = get_cairo_calldata(evm_calldata)
cairo_calldata[-1] = 2 ** 128 # tamper with calldata to make it invalid
tampered_calldata1 = list(cairo_calldata)
tampered_calldata1[-1] = 2 ** 128
exc_msg = rf"Value {2**128}, in range check builtin \d*, is out of range \[0, {2**128}\)\."
with pytest.raises(StarkException, match=exc_msg):
await starknet.deploy(friendly_def, cairo_calldata)
await starknet.deploy(friendly_def, tampered_calldata1)
tampered_calldata2 = list(cairo_calldata)
tampered_calldata2[0] -= 10
with pytest.raises(StarkException):
await starknet.deploy(friendly_def, tampered_calldata2)
tampered_calldata3 = list(cairo_calldata)
tampered_calldata3[0] += 10
with pytest.raises(StarkException):
await starknet.deploy(friendly_def, tampered_calldata3)


@pytest.mark.asyncio
Expand Down
10 changes: 10 additions & 0 deletions tests/benchmark/calldatacopy.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
pragma solidity >=0.8.6;

contract WARP {
function callMe() public payable returns (bytes4) {
assembly {
calldatacopy(0x0, 0, 4)
return(0x0, 4)
}
}
}
41 changes: 41 additions & 0 deletions tests/benchmark/calldatacopy_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import os
import tempfile

import pytest
from cli.encoding import get_evm_calldata
from starkware.starknet.compiler.compile import compile_starknet_files
from starkware.starknet.testing.state import StarknetState
from yul.main import transpile_from_solidity
from yul.starknet_utils import deploy_contract, invoke_method
from yul.utils import cairoize_bytes

from warp.logging.generateMarkdown import steps_in_function

warp_root = os.path.abspath(os.path.join(__file__, "../../.."))
test_dir = __file__


@pytest.mark.asyncio
async def test_calldatacopy():
sol_file = test_dir[:-8] + ".sol"
program_info = transpile_from_solidity(sol_file, "WARP")
tmp = tempfile.NamedTemporaryFile(mode="w", suffix=".cairo", delete=False)
tmp.write(program_info["cairo_code"])
tmp.close()
cairo_path = f"{warp_root}/warp/cairo-src"
contract_definition = compile_starknet_files(
[tmp.name], debug_info=True, cairo_path=[cairo_path]
)

starknet = await StarknetState.empty()
contract_address = await deploy_contract(
starknet, program_info, contract_definition
)

evm_calldata = get_evm_calldata(program_info["sol_abi"], "callMe", [])
[first_four_bytes], _ = cairoize_bytes(evm_calldata[:4])
res = await invoke_method(starknet, program_info, contract_address, "callMe")
steps_in_function(sol_file, "callMe", res, "calldatacopy_test")
assert res.retdata == [4, 1, first_four_bytes]

os.unlink(tmp.name)
26 changes: 26 additions & 0 deletions tests/cairo/array-aligned-create.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
%builtins output range_check bitwise

from evm.array import array_create_from_memory
from evm.memory import mload, mstore
from starkware.cairo.common.cairo_builtins import BitwiseBuiltin
from starkware.cairo.common.default_dict import default_dict_finalize, default_dict_new
from starkware.cairo.common.serialize import serialize_word
from starkware.cairo.common.uint256 import Uint256

func main{output_ptr : felt*, range_check_ptr, bitwise_ptr : BitwiseBuiltin*}():
alloc_locals
let (memory_dict) = default_dict_new(0)
let dict_start = memory_dict
with memory_dict:
# we don't do assertions here, since if one fails we can't observe others
mstore(0, Uint256(5000, 0xabcd * 256 ** 14 + 0x123456))
mstore(32, Uint256(0xdeadbeef, 0xcafebabe))
let (array) = array_create_from_memory(0, 64)
serialize_word(array[0])
serialize_word(array[1])
serialize_word(array[2])
serialize_word(array[3])
end
default_dict_finalize(dict_start, memory_dict, 0)
return ()
end
6 changes: 6 additions & 0 deletions tests/cairo/array-aligned-create.cairo.gold
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Program output:
228362408135220253930399759055430235222
5000
3405691582
3735928559

29 changes: 29 additions & 0 deletions tests/cairo/array-unaligned-create.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
%builtins output range_check bitwise

from evm.array import array_create_from_memory
from evm.memory import mload, mstore
from starkware.cairo.common.cairo_builtins import BitwiseBuiltin
from starkware.cairo.common.default_dict import default_dict_finalize, default_dict_new
from starkware.cairo.common.serialize import serialize_word
from starkware.cairo.common.uint256 import Uint256

func main{output_ptr : felt*, range_check_ptr, bitwise_ptr : BitwiseBuiltin*}():
alloc_locals
let (memory_dict) = default_dict_new(0)
let dict_start = memory_dict
with memory_dict:
# we don't do assertions here, since if one fails we can't observe others
mstore(4, Uint256(5000, 0xabcd * 256 ** 14 + 0x123456))
mstore(36, Uint256(0xdeadbeef, 0xcafebabe))
let (array) = array_create_from_memory(4, 64)
serialize_word(array[0])
serialize_word(array[1])
serialize_word(array[2])
serialize_word(array[3])
let (array) = array_create_from_memory(36, 32)
serialize_word(array[0])
serialize_word(array[1])
end
default_dict_finalize(dict_start, memory_dict, 0)
return ()
end
8 changes: 8 additions & 0 deletions tests/cairo/array-unaligned-create.cairo.gold
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Program output:
228362408135220253930399759055430235222
5000
3405691582
3735928559
3405691582
3735928559

38 changes: 21 additions & 17 deletions tests/golden/ERC20.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ end
func constructor{pedersen_ptr : HashBuiltin*, range_check_ptr, syscall_ptr : felt*}(
calldata_size, calldata_len, calldata : felt*):
alloc_locals
validate_array(calldata_len, calldata)
validate_array(calldata_size, calldata_len, calldata)
let (memory_dict) = default_dict_new(0)
let memory_dict_start = memory_dict
let msize = 0
Expand All @@ -55,7 +55,7 @@ func __main{
syscall_ptr : felt*}(calldata_size, calldata_len, calldata : felt*) -> (
returndata_size, returndata_len, returndata : felt*):
alloc_locals
validate_array(calldata_len, calldata)
validate_array(calldata_size, calldata_len, calldata)
let (__fp__, _) = get_fp_and_pc()
local exec_env_ : ExecutionEnvironment = ExecutionEnvironment(calldata_size=calldata_size, calldata_len=calldata_len, calldata=calldata, returndata_size=0, returndata_len=0, returndata=cast(0, felt*), to_returndata_size=0, to_returndata_len=0, to_returndata=cast(0, felt*))
let exec_env : ExecutionEnvironment* = &exec_env_
Expand Down Expand Up @@ -137,8 +137,8 @@ func checked_add_uint256{range_check_ptr}(x : Uint256, y : Uint256) -> (sum : Ui
end

func fun_transfer{
memory_dict : DictAccess*, msize, pedersen_ptr : HashBuiltin*, range_check_ptr,
syscall_ptr : felt*}(
bitwise_ptr : BitwiseBuiltin*, memory_dict : DictAccess*, msize,
pedersen_ptr : HashBuiltin*, range_check_ptr, syscall_ptr : felt*}(
var_sender : Uint256, var_recipient : Uint256, var_amount : Uint256) -> ():
alloc_locals
uint256_mstore(offset=Uint256(low=0, high=0), value=var_sender)
Expand Down Expand Up @@ -167,8 +167,8 @@ func fun_transfer{
end

func fun_transferFrom{
memory_dict : DictAccess*, msize, pedersen_ptr : HashBuiltin*, range_check_ptr,
syscall_ptr : felt*}(
bitwise_ptr : BitwiseBuiltin*, memory_dict : DictAccess*, msize,
pedersen_ptr : HashBuiltin*, range_check_ptr, syscall_ptr : felt*}(
var_sender : Uint256, var_recipient : Uint256, var_amount : Uint256) -> (var : Uint256):
alloc_locals
fun_transfer(var_sender, var_recipient, var_amount)
Expand Down Expand Up @@ -220,8 +220,9 @@ func abi_decode_addresst_uint256{
end

func fun_mint{
memory_dict : DictAccess*, msize, pedersen_ptr : HashBuiltin*, range_check_ptr,
syscall_ptr : felt*}(var_to : Uint256, var_amount : Uint256) -> (var : Uint256):
bitwise_ptr : BitwiseBuiltin*, memory_dict : DictAccess*, msize,
pedersen_ptr : HashBuiltin*, range_check_ptr, syscall_ptr : felt*}(
var_to : Uint256, var_amount : Uint256) -> (var : Uint256):
alloc_locals
uint256_mstore(offset=Uint256(low=0, high=0), value=var_to)
uint256_mstore(offset=Uint256(low=32, high=0), value=Uint256(low=0, high=0))
Expand Down Expand Up @@ -250,8 +251,9 @@ func abi_decode_address{
end

func getter_fun_balances{
memory_dict : DictAccess*, msize, pedersen_ptr : HashBuiltin*, range_check_ptr,
syscall_ptr : felt*}(key : Uint256) -> (ret__warp_mangled : Uint256):
bitwise_ptr : BitwiseBuiltin*, memory_dict : DictAccess*, msize,
pedersen_ptr : HashBuiltin*, range_check_ptr, syscall_ptr : felt*}(key : Uint256) -> (
ret__warp_mangled : Uint256):
alloc_locals
uint256_mstore(offset=Uint256(low=0, high=0), value=key)
uint256_mstore(offset=Uint256(low=32, high=0), value=Uint256(low=0, high=0))
Expand All @@ -262,8 +264,9 @@ func getter_fun_balances{
end

func fun_balanceOf{
memory_dict : DictAccess*, msize, pedersen_ptr : HashBuiltin*, range_check_ptr,
syscall_ptr : felt*}(var_account : Uint256) -> (var_ : Uint256):
bitwise_ptr : BitwiseBuiltin*, memory_dict : DictAccess*, msize,
pedersen_ptr : HashBuiltin*, range_check_ptr, syscall_ptr : felt*}(
var_account : Uint256) -> (var_ : Uint256):
alloc_locals
uint256_mstore(offset=Uint256(low=0, high=0), value=var_account)
uint256_mstore(offset=Uint256(low=32, high=0), value=Uint256(low=0, high=0))
Expand All @@ -274,8 +277,9 @@ func fun_balanceOf{
end

func fun_transfer_73{
memory_dict : DictAccess*, msize, pedersen_ptr : HashBuiltin*, range_check_ptr,
syscall_ptr : felt*}(var_recipient : Uint256, var_amount : Uint256) -> (var : Uint256):
bitwise_ptr : BitwiseBuiltin*, memory_dict : DictAccess*, msize,
pedersen_ptr : HashBuiltin*, range_check_ptr, syscall_ptr : felt*}(
var_recipient : Uint256, var_amount : Uint256) -> (var : Uint256):
alloc_locals
let (__warp_subexpr_0 : Uint256) = caller()
fun_transfer(__warp_subexpr_0, var_recipient, var_amount)
Expand All @@ -284,9 +288,9 @@ func fun_transfer_73{
end

func __warp_block_2{
exec_env : ExecutionEnvironment*, memory_dict : DictAccess*, msize,
pedersen_ptr : HashBuiltin*, range_check_ptr, syscall_ptr : felt*, termination_token}() -> (
):
bitwise_ptr : BitwiseBuiltin*, exec_env : ExecutionEnvironment*, memory_dict : DictAccess*,
msize, pedersen_ptr : HashBuiltin*, range_check_ptr, syscall_ptr : felt*,
termination_token}() -> ():
alloc_locals
let (__warp_subexpr_0 : Uint256) = calldatasize()
abi_decode(__warp_subexpr_0)
Expand Down
Loading

0 comments on commit 9d66d67

Please sign in to comment.