mirror of
https://github.com/logos-co/SimulationsFramework.git
synced 2025-02-20 17:58:23 +00:00
commit
48da9c5730
2
.dockerignore
Normal file
2
.dockerignore
Normal file
@ -0,0 +1,2 @@
|
||||
*.md
|
||||
.venv
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1,3 @@
|
||||
.idea/
|
||||
.venv/
|
||||
*__pycache__*
|
34
Dockerfile
Normal file
34
Dockerfile
Normal file
@ -0,0 +1,34 @@
|
||||
# BUILD IMAGE --------------------------------------------------------
|
||||
|
||||
FROM rust as builder
|
||||
|
||||
# Update default packages
|
||||
RUN apt-get update
|
||||
|
||||
# Get tools needed
|
||||
RUN apt-get install -y git
|
||||
|
||||
# Get the simulation code
|
||||
WORKDIR /rust-app
|
||||
RUN git clone https://github.com/logos-co/consensus-research.git
|
||||
|
||||
# Compile it
|
||||
WORKDIR /rust-app/consensus-research
|
||||
RUN cargo build --profile release-opt --bin snow-family
|
||||
|
||||
|
||||
# ACTUAL IMAGE ------------------------------------------------------
|
||||
FROM python
|
||||
|
||||
COPY --from=builder /rust-app/consensus-research/target/release-opt/snow-family /usr/local/bin/snow-family
|
||||
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
|
||||
RUN pip install -r requirements.txt
|
||||
|
||||
ENV PYTHONPATH "${PYTHONPATH}:src"
|
||||
|
||||
ENTRYPOINT ["python", "src/main.py"]
|
||||
|
||||
|
57
README.md
Executable file
57
README.md
Executable file
@ -0,0 +1,57 @@
|
||||
# Simulations Framework
|
||||
|
||||
This framework is to run simulations, as well as being able to obtain plots from the results in an easy-one command manner.
|
||||
|
||||
Simulations supported:
|
||||
- Snow family: https://github.com/logos-co/consensus-research (default)
|
||||
|
||||
## How to use
|
||||
|
||||
In order to build the image, simply run:
|
||||
|
||||
`docker build -t desired_name_of_docker_image .`
|
||||
|
||||
In order to tell the container what to do, you need to specify the options in a configuration file, as json.
|
||||
More information in:
|
||||
|
||||
|
||||
Supported parameters:
|
||||
- Run parameters `--run` or `-r`
|
||||
- `both` (default) (to-do)
|
||||
- `simulation`
|
||||
- `plotter` (to-do)
|
||||
- Simulation type `--protocol` or `-p` (to-do)
|
||||
- `snow-family` (default, not changeable)
|
||||
- Configuration file `--configuration-file` or `-cf`
|
||||
- <configuration_file_name.json>
|
||||
|
||||
In order to receive the information, plots, and whatever is done inside the container, a shared folder is
|
||||
provided inside this repository. Before running the container,
|
||||
|
||||
### Example of execution:
|
||||
|
||||
`docker run --rm -v </your/path/to/SimulationsFramework/shared>:/app/shared <desired_name_of_docker_image>
|
||||
-r <simulation> -cf <configuration_file_name.json>`
|
||||
|
||||
The parameters inside `< >` can be changed. Where:
|
||||
|
||||
- `docker run --rm` will launch a docker container, and after it finishes, it will automatically destroy itself.
|
||||
- `-v </your/path/to/SimulationsFramework/shared>:/app/shared` is the mount folder that will be used to share data
|
||||
between the container and the host. In order to make things easier, the folder inside this repo can be used for that.
|
||||
Still, any desired folder can be put here, as long as it is in absolute path. `/app/shared` is a internal framework
|
||||
location, so this needs to remain unchanged.
|
||||
- `<desired_name_of_docker_image>` is the docker image name previously created.
|
||||
- `-r <simulation>` is the type of execution we want. It can be only simulation `simulation`, only plotting `plotter`,
|
||||
or simulation and plot `both`. This last option is as default, so if this is the case, it is something that needs to
|
||||
be specified.
|
||||
- `-cf <configuration_file_name.json>` is the configuration file where we set up what we want to do in the execution.
|
||||
This file needs to be in our shared host folder.
|
||||
|
||||
So, an example of a command would be:
|
||||
|
||||
`docker run --rm -v /mnt/d/Projects/SimulationsFramework/shared:/app/shared simulation-framework
|
||||
-r simulation -cf config_example.json`
|
||||
|
||||
## Project structure
|
||||
|
||||
(to-do)
|
@ -1,38 +0,0 @@
|
||||
{
|
||||
"consensus_settings": {
|
||||
"snow_ball": {
|
||||
"quorum_size": 14,
|
||||
"sample_size": 20,
|
||||
"decision_threshold": 20
|
||||
}
|
||||
},
|
||||
"distribution": {
|
||||
"yes": 0.6,
|
||||
"no": 0.4,
|
||||
"none": 0.0
|
||||
},
|
||||
"byzantine_settings": {
|
||||
"total_size": 10000,
|
||||
"distribution": {
|
||||
"honest": 1.0,
|
||||
"infantile": 0.0,
|
||||
"random": 0.0,
|
||||
"omniscient": 0.0
|
||||
}
|
||||
},
|
||||
"wards": [
|
||||
{
|
||||
"time_to_finality": {
|
||||
"ttf_threshold" : 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"network_modifiers": [
|
||||
{
|
||||
"random_drop": {
|
||||
"drop_rate": 0.01
|
||||
}
|
||||
}
|
||||
],
|
||||
"seed" : 18042022
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
# Python Imports
|
||||
import typer
|
||||
|
||||
# Project Imports
|
||||
from Utilities.Files.Json.simulation_config_parser import SimulationConfigParser
|
||||
from runner import run_simulation
|
||||
|
||||
|
||||
def main(
|
||||
# todo put in output format possible names (-f --output-format)
|
||||
output_format: str = typer.Option(..., "--output-format", "-f"),
|
||||
input_settings: str = typer.Option(..., "--input-settings", "-i"),
|
||||
output_file: str = typer.Option(..., "--output-file", "-o")
|
||||
):
|
||||
# Check config file
|
||||
parser = SimulationConfigParser(input_settings)
|
||||
parser.read_content()
|
||||
# Calls simulation with configuration
|
||||
run_simulation(output_format, input_settings, output_file)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
typer.run(main)
|
@ -1,9 +0,0 @@
|
||||
# Python Imports
|
||||
import os
|
||||
|
||||
# Project Imports
|
||||
from Utilities.env_variables import binary_path
|
||||
|
||||
|
||||
def run_simulation(output_format, input_settings, output_file):
|
||||
os.system(binary_path + " -f " + output_format + " -i " + input_settings + " -o " + output_file)
|
@ -1,20 +0,0 @@
|
||||
from Utilities import env_variables
|
||||
from Utilities.Files.Json.json_utils import read_json, validate_json
|
||||
|
||||
|
||||
class SimulationConfigParser:
|
||||
|
||||
def __init__(self, file_path):
|
||||
self._file_path = file_path
|
||||
self._configuration = None
|
||||
|
||||
def read_content(self):
|
||||
# Retrieve raw info
|
||||
json_configuration = read_json(self._file_path)
|
||||
|
||||
# Retrieve valid schema
|
||||
json_schema = read_json(env_variables.schema_path)
|
||||
|
||||
# Validate
|
||||
validate_json(json_configuration, json_schema)
|
||||
self._configuration = json_configuration
|
@ -1,4 +0,0 @@
|
||||
# Workaround while docker is not set up
|
||||
|
||||
binary_path = "C:/Users/Alberto/Desktop/Status/consensus-prototypes/target/release-opt/consensus-simulations.exe"
|
||||
schema_path = "../Utilities/Files/Schemas/configuration_schema.json"
|
BIN
requirements.txt
Executable file
BIN
requirements.txt
Executable file
Binary file not shown.
44
shared/config_example.json
Normal file
44
shared/config_example.json
Normal file
@ -0,0 +1,44 @@
|
||||
{
|
||||
"arguments": {"output-format": "csv", "output-file": "test"},
|
||||
"simulation": {
|
||||
"consensus_settings": {
|
||||
"snow_ball": {
|
||||
"quorum_size": 14,
|
||||
"sample_size": 20,
|
||||
"decision_threshold": 20
|
||||
}
|
||||
},
|
||||
"distribution": {
|
||||
"yes": 0.6,
|
||||
"no": 0.4,
|
||||
"none": 0.0
|
||||
},
|
||||
"byzantine_settings": {
|
||||
"total_size": 10000,
|
||||
"distribution": {
|
||||
"honest": 1.0,
|
||||
"infantile": 0.0,
|
||||
"random": 0.0,
|
||||
"omniscient": 0.0
|
||||
}
|
||||
},
|
||||
"wards": [
|
||||
{
|
||||
"time_to_finality": {
|
||||
"ttf_threshold": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"network_modifiers": [
|
||||
{
|
||||
"random_drop": {
|
||||
"drop_rate": 0.01
|
||||
}
|
||||
}
|
||||
],
|
||||
"seed": 18042022
|
||||
},
|
||||
"plotting": {
|
||||
"test": "test"
|
||||
}
|
||||
}
|
0
Plotter/__init__.py → src/__init__.py
Normal file → Executable file
0
Plotter/__init__.py → src/__init__.py
Normal file → Executable file
1
src/configuration_settings.json
Executable file
1
src/configuration_settings.json
Executable file
@ -0,0 +1 @@
|
||||
{"consensus_settings": {"snow_ball": {"quorum_size": 14, "sample_size": 20, "decision_threshold": 20}}, "distribution": {"yes": 0.6, "no": 0.4, "none": 0.0}, "byzantine_settings": {"total_size": 10000, "distribution": {"honest": 1.0, "infantile": 0.0, "random": 0.0, "omniscient": 0.0}}, "wards": [{"time_to_finality": {"ttf_threshold": 1}}], "network_modifiers": [{"random_drop": {"drop_rate": 0.01}}], "seed": 18042022}
|
27
src/main.py
Executable file
27
src/main.py
Executable file
@ -0,0 +1,27 @@
|
||||
# Python Imports
|
||||
import typer
|
||||
|
||||
# Project Imports
|
||||
from src.simulation_runner.runner import run_simulation
|
||||
from src.utilities.files.json.simulation_config_parser import SimulationConfigParser
|
||||
|
||||
|
||||
def main(
|
||||
run_type: str = typer.Option(..., "--run", "-r"),
|
||||
configuration_file: str = typer.Option(..., "--configuration-file", "-cf")
|
||||
):
|
||||
parser = SimulationConfigParser(configuration_file)
|
||||
arguments_config, simulation_config, plotter_config = parser.read_content()
|
||||
# Calls depending on json config
|
||||
if run_type == "simulation":
|
||||
run_simulation(arguments_config, simulation_config)
|
||||
elif run_type == "plotter":
|
||||
# run_plotter()
|
||||
pass
|
||||
else:
|
||||
run_simulation()
|
||||
# run_plotter()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
typer.run(main)
|
18
src/simulation_runner/runner.py
Normal file
18
src/simulation_runner/runner.py
Normal file
@ -0,0 +1,18 @@
|
||||
# Python Imports
|
||||
import os
|
||||
|
||||
# Project Imports
|
||||
from src.utilities.env_variables import BINARY_PATH, CONFIGURATION_SETTINGS, SHARED_FOLDER
|
||||
from src.utilities.files.json.json_utils import write_json
|
||||
|
||||
|
||||
def run_simulation(arguments_config: dict, simulation_config: dict):
|
||||
|
||||
write_json(simulation_config, CONFIGURATION_SETTINGS)
|
||||
|
||||
os.system(BINARY_PATH
|
||||
+ " -f " + arguments_config["output-format"]
|
||||
+ " -i " + CONFIGURATION_SETTINGS + " -o "
|
||||
+ arguments_config["output-file"])
|
||||
|
||||
os.system("mv " + arguments_config["output-file"] + "." + arguments_config["output-format"] + " " + SHARED_FOLDER)
|
11
src/utilities/env_variables.py
Normal file
11
src/utilities/env_variables.py
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
# Binary
|
||||
BINARY_PATH = "snow-family"
|
||||
CONFIGURATION_SETTINGS = "shared/configuration_settings.json"
|
||||
|
||||
# Schemas
|
||||
ARGUMENTS_SCHEMA_PATH = "src/utilities/files/schemas/arguments_schema.json"
|
||||
CONFIGURATION_SCHEMA_PATH = "src/utilities/files/schemas/snow_family_configuration_schema.json"
|
||||
|
||||
# Shared folder
|
||||
SHARED_FOLDER = "shared/"
|
@ -3,13 +3,18 @@ import json
|
||||
import jsonschema
|
||||
|
||||
|
||||
def read_json(file_path):
|
||||
def read_json(file_path: str) -> dict:
|
||||
with open(file_path, "r") as file:
|
||||
json_content = json.load(file)
|
||||
|
||||
return json_content
|
||||
|
||||
|
||||
def validate_json(json_content, json_schema):
|
||||
def write_json(info: dict, file_path: str):
|
||||
with open(file_path, "w") as file:
|
||||
json.dump(info, file)
|
||||
|
||||
|
||||
def validate_json(json_content: dict, json_schema: dict):
|
||||
jsonschema.validate(instance=json_content, schema=json_schema)
|
||||
|
32
src/utilities/files/json/simulation_config_parser.py
Normal file
32
src/utilities/files/json/simulation_config_parser.py
Normal file
@ -0,0 +1,32 @@
|
||||
# Project Imports
|
||||
from src.utilities import env_variables
|
||||
from src.utilities.files.json.json_utils import read_json, validate_json
|
||||
|
||||
|
||||
class SimulationConfigParser:
|
||||
_file_path: str
|
||||
|
||||
def __init__(self, file_path: str):
|
||||
self._file_path = file_path
|
||||
|
||||
def read_content(self) -> tuple[dict, dict, dict]:
|
||||
# Retrieve raw info
|
||||
json_configuration = read_json(env_variables.SHARED_FOLDER + self._file_path)
|
||||
|
||||
# Split two parts
|
||||
arguments_config = json_configuration["arguments"]
|
||||
simulation_config = json_configuration["simulation"]
|
||||
# plotter_config = json_configuration["plotter"]
|
||||
|
||||
# Retrieve valid schemas
|
||||
arguments_json_schema = read_json(env_variables.ARGUMENTS_SCHEMA_PATH)
|
||||
config_json_schema = read_json(env_variables.CONFIGURATION_SCHEMA_PATH)
|
||||
# plotter_json_schema = read_json(env_variables.plotter_schema_path)
|
||||
|
||||
# Validate
|
||||
validate_json(arguments_config, arguments_json_schema)
|
||||
validate_json(simulation_config, config_json_schema)
|
||||
# validate_json(plotter_config, plotter_json_schema)
|
||||
|
||||
# return simulation_config, plotter_config
|
||||
return arguments_config, simulation_config, {}
|
17
src/utilities/files/schemas/arguments_schema.json
Executable file
17
src/utilities/files/schemas/arguments_schema.json
Executable file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"output-format": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"parquet",
|
||||
"csv",
|
||||
"json"
|
||||
],
|
||||
"default": "parquet"
|
||||
},
|
||||
"output-file": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
0
src/utilities/files/schemas/plotter_schema.json
Executable file
0
src/utilities/files/schemas/plotter_schema.json
Executable file
@ -19,7 +19,7 @@
|
||||
},
|
||||
"required": ["quorum_size", "sample_size", "decision_threshold"]
|
||||
},
|
||||
"glacier": {
|
||||
"claro": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"evidence_alpha": {"type": "number"},
|
@ -2,9 +2,9 @@
|
||||
import os.path
|
||||
|
||||
# Project Imports
|
||||
from Utilities.Files.SimulationDataTypes.JsonDataSimulationHandler import JsonDataSimulationHandler
|
||||
from Utilities.Files.SimulationDataTypes.CsvDataSimulationHandler import CsvDataSimulationHandler
|
||||
from Utilities.Files.SimulationDataTypes.ParquetSimulationDataHandler import ParquetDataSimulationHandler
|
||||
from src.utilities.files.simulation_data_types.json_data_simulation_handler import JsonDataSimulationHandler
|
||||
from src.utilities.files.simulation_data_types.csv_data_simulation_handler import CsvDataSimulationHandler
|
||||
from src.utilities.files.simulation_data_types.parquet_simulation_data_handler import ParquetDataSimulationHandler
|
||||
|
||||
handlers = {'.csv': CsvDataSimulationHandler,
|
||||
'.json': JsonDataSimulationHandler,
|
@ -1,4 +1,4 @@
|
||||
from Utilities.Files.SimulationDataTypes.BaseDataSimulationHandler import BaseDataSimulationHandler
|
||||
from src.utilities.files.simulation_data_types.base_data_simulation_handler import BaseDataSimulationHandler
|
||||
|
||||
|
||||
class CsvDataSimulationHandler(BaseDataSimulationHandler):
|
@ -1,4 +1,4 @@
|
||||
from Utilities.Files.SimulationDataTypes.BaseDataSimulationHandler import BaseDataSimulationHandler
|
||||
from src.utilities.files.simulation_data_types.base_data_simulation_handler import BaseDataSimulationHandler
|
||||
|
||||
|
||||
class JsonDataSimulationHandler(BaseDataSimulationHandler):
|
@ -1,4 +1,4 @@
|
||||
from Utilities.Files.SimulationDataTypes.BaseDataSimulationHandler import BaseDataSimulationHandler
|
||||
from src.utilities.files.simulation_data_types.base_data_simulation_handler import BaseDataSimulationHandler
|
||||
|
||||
|
||||
class ParquetDataSimulationHandler(BaseDataSimulationHandler):
|
Loading…
x
Reference in New Issue
Block a user