Skip to content
This repository has been archived by the owner on Dec 15, 2023. It is now read-only.

Commit

Permalink
Add dump path check (#182)
Browse files Browse the repository at this point in the history
* Check if dump path dir exists

* Fix case when no parent dir

* Apply check when dumping via http
  • Loading branch information
FabijanC authored Jul 15, 2022
1 parent 8557cf9 commit 4f1ce69
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 10 deletions.
7 changes: 6 additions & 1 deletion starknet_devnet/blueprints/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from starknet_devnet.fee_token import FeeToken

from starknet_devnet.state import state
from starknet_devnet.util import StarknetDevnetException
from starknet_devnet.util import StarknetDevnetException, check_valid_dump_path

base = Blueprint("base", __name__)

Expand Down Expand Up @@ -61,6 +61,11 @@ def dump():
if not dump_path:
raise StarknetDevnetException(message="No path provided.", status_code=400)

try:
check_valid_dump_path(dump_path)
except ValueError as error:
raise StarknetDevnetException(status_code=400, message=str(error)) from error

state.dumper.dump(dump_path)
return Response(status=200)

Expand Down
16 changes: 11 additions & 5 deletions starknet_devnet/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@
A server exposing Starknet functionalities as API endpoints.
"""

import sys
from pickle import UnpicklingError
import sys

from flask import Flask, jsonify
from flask_cors import CORS
import meinheld

from starkware.starkware_utils.error_handling import StarkException

from .blueprints.base import base
from .blueprints.gateway import gateway
from .blueprints.feeder_gateway import feeder_gateway
from .blueprints.postman import postman
from .blueprints.rpc import rpc
from .util import DumpOn, parse_args
from .state import state
from .util import DumpOn, check_valid_dump_path, parse_args
from .starknet_wrapper import DevnetConfig
from .state import state

app = Flask(__name__)
CORS(app)
Expand All @@ -44,6 +44,12 @@ def generate_accounts(args):

def set_dump_options(args):
"""Assign dumping options from args to state."""
if args.dump_path:
try:
check_valid_dump_path(args.dump_path)
except ValueError as error:
sys.exit(str(error))

state.dumper.dump_path = args.dump_path
state.dumper.dump_on = args.dump_on

Expand Down Expand Up @@ -89,8 +95,8 @@ def main():
# starknet_wrapper.origin = origin

load_dumped(args)
generate_accounts(args)
set_dump_options(args)
generate_accounts(args)
enable_lite_mode(args)
set_start_time(args)
set_gas_price(args)
Expand Down
15 changes: 14 additions & 1 deletion starknet_devnet/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
Utility functions used across the project.
"""

import argparse
from dataclasses import dataclass
from enum import Enum, auto
import argparse
import os
import sys
from typing import List, Dict, Union

Expand Down Expand Up @@ -302,3 +303,15 @@ def to_bytes(value: Union[int, bytes]) -> bytes:
If bytes, return the received value
"""
return value if isinstance(value, bytes) else value.to_bytes(32, "big")

def check_valid_dump_path(dump_path: str):
"""Checks if dump path is a directory. Raises ValueError if not."""

dump_path_dir = os.path.dirname(dump_path)

if not dump_path_dir:
# dump_path is just a file, with no parent dir
return

if not os.path.isdir(dump_path_dir):
raise ValueError(f"Invalid dump path: directory '{dump_path_dir}' not found.")
26 changes: 23 additions & 3 deletions test/test_dump.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def test_load_if_no_file():
"""Test loading if dump file not present."""
assert_no_dump_present(DUMP_PATH)
devnet_proc = ACTIVE_DEVNET.start("--load-path", DUMP_PATH, stderr=subprocess.PIPE)
assert devnet_proc.returncode != 0
assert devnet_proc.returncode == 1
expected_msg = f"Error: Cannot load from {DUMP_PATH}. Make sure the file exists and contains a Devnet dump.\n"
assert expected_msg == devnet_proc.stderr.read().decode("utf-8")

Expand All @@ -117,6 +117,26 @@ def test_dumping_if_path_not_provided():
resp = send_dump_request()
assert resp.status_code == 400

NONEXISTENT_DIR = "nonexistent-dir"

def test_dumping_if_nonexistent_dir_via_cli():
"""Assert failure if dumping attempted via cli with a path containing a nonexistent dir"""
invalid_path = os.path.join(NONEXISTENT_DIR, DUMP_PATH)
devnet_proc = ACTIVE_DEVNET.start("--dump-path", invalid_path, stderr=subprocess.PIPE)
assert devnet_proc.returncode == 1

expected_msg = f"Invalid dump path: directory '{NONEXISTENT_DIR}' not found.\n"
assert expected_msg == devnet_proc.stderr.read().decode("utf-8")

@devnet_in_background()
def test_dumping_if_nonexistent_dir_via_http():
"""Assert failure if dumping attempted via http with a path containing a nonexistent dir"""
invalid_path = os.path.join(NONEXISTENT_DIR, DUMP_PATH)

resp = send_dump_request(dump_path=invalid_path)
assert resp.json()["message"] == f"Invalid dump path: directory '{NONEXISTENT_DIR}' not found."
assert resp.status_code == 400

@devnet_in_background("--dump-path", DUMP_PATH)
def test_dumping_if_path_provided_as_cli_option():
"""Test dumping if path provided as CLI option"""
Expand Down Expand Up @@ -207,15 +227,15 @@ def test_invalid_dump_on_option():
stderr=subprocess.PIPE
)

assert devnet_proc.returncode != 0
assert devnet_proc.returncode == 1
expected_msg = b"Error: Invalid --dump-on option: obviously-invalid. Valid options: exit, transaction\n"
assert devnet_proc.stderr.read() == expected_msg

def test_dump_path_not_present_with_dump_on_present():
"""Test behavior when dump-path is not present and dump-on is."""
devnet_proc = ACTIVE_DEVNET.start("--dump-on", "exit", stderr=subprocess.PIPE)

assert devnet_proc.returncode != 0
assert devnet_proc.returncode == 1
expected_msg = b"Error: --dump-path required if --dump-on present\n"
assert devnet_proc.stderr.read() == expected_msg

Expand Down

0 comments on commit 4f1ce69

Please sign in to comment.