-
Notifications
You must be signed in to change notification settings - Fork 64
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Netting Project: PR 1 of n #409
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,6 @@ | ||
# Netting project gitignore | ||
apps/netting/data/ | ||
|
||
# Byte-compiled / optimized / DLL files | ||
__pycache__/ | ||
*.py[cod] | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
# Byte-compiled / optimized / DLL files | ||
__pycache__/ | ||
*.py[cod] | ||
*$py.class | ||
*.csv | ||
|
||
# C extensions | ||
*.so | ||
|
||
# Distribution / packaging | ||
.Python | ||
build/ | ||
develop-eggs/ | ||
dist/ | ||
downloads/ | ||
eggs/ | ||
.eggs/ | ||
lib/ | ||
lib64/ | ||
parts/ | ||
sdist/ | ||
var/ | ||
wheels/ | ||
pip-wheel-metadata/ | ||
share/python-wheels/ | ||
*.egg-info/ | ||
.installed.cfg | ||
*.egg | ||
MANIFEST | ||
|
||
# PyInstaller | ||
# Usually these files are written by a python script from a template | ||
# before PyInstaller builds the exe, so as to inject date/other infos into it. | ||
*.manifest | ||
*.spec | ||
|
||
# Installer logs | ||
pip-log.txt | ||
pip-delete-this-directory.txt | ||
|
||
# Unit test / coverage reports | ||
htmlcov/ | ||
.tox/ | ||
.nox/ | ||
.coverage | ||
.coverage.* | ||
.cache | ||
nosetests.xml | ||
coverage.xml | ||
*.cover | ||
*.py,cover | ||
.hypothesis/ | ||
.pytest_cache/ | ||
|
||
# Translations | ||
*.mo | ||
*.pot | ||
|
||
# Django stuff: | ||
*.log | ||
local_settings.py | ||
db.sqlite3 | ||
db.sqlite3-journal | ||
|
||
# Flask stuff: | ||
instance/ | ||
.webassets-cache | ||
|
||
# Scrapy stuff: | ||
.scrapy | ||
|
||
# Sphinx documentation | ||
docs/_build/ | ||
|
||
# PyBuilder | ||
target/ | ||
|
||
# Jupyter Notebook | ||
.ipynb_checkpoints | ||
|
||
# IPython | ||
profile_default/ | ||
ipython_config.py | ||
|
||
# pyenv | ||
.python-version | ||
|
||
# pipenv | ||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. | ||
# However, in case of collaboration, if having platform-specific dependencies or dependencies | ||
# having no cross-platform support, pipenv may install dependencies that don't work, or not | ||
# install all needed dependencies. | ||
#Pipfile.lock | ||
|
||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow | ||
__pypackages__/ | ||
|
||
# Celery stuff | ||
celerybeat-schedule | ||
celerybeat.pid | ||
|
||
# SageMath parsed files | ||
*.sage.py | ||
|
||
# Environments | ||
.env | ||
.venv | ||
env/ | ||
venv/ | ||
ENV/ | ||
env.bak/ | ||
venv.bak/ | ||
|
||
# Spyder project settings | ||
.spyderproject | ||
.spyproject | ||
|
||
# Rope project settings | ||
.ropeproject | ||
|
||
# mkdocs documentation | ||
/site | ||
|
||
# mypy | ||
.mypy_cache/ | ||
.dmypy.json | ||
dmypy.json | ||
|
||
# Pyre type checker | ||
.pyre/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# netting | ||
Netting application for MPC |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# Number of transactions | ||
NUMTX = 500000 | ||
|
||
# Number of parties | ||
NUM_CLIENTS = 64 | ||
|
||
# Average payment amount | ||
mu_tx = 10000.00 | ||
mu_bal = 10000.00 | ||
|
||
# Standard deviation | ||
sigma_tx = 100.00 | ||
sigma_bal = 100.00 | ||
|
||
# File name info | ||
tx_file_prefix = "party_" | ||
tx_file_suffix = "_tx_data.csv" | ||
|
||
bal_file_prefix = "party_" | ||
bal_file_suffix = "_bal_data.csv" | ||
|
||
NETTING_BASE_DIR = "/usr/src/HoneyBadgerMPC/apps/netting/" | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
all: clean gen_data | ||
|
||
clean: | ||
rm -rf data/ | ||
|
||
gen_data: | ||
python3 scripts/generate_data.py | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just to remain consistent with the code base, let's use
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import random | ||
import os | ||
import shutil | ||
import logging | ||
from apps.netting.config.config import ( | ||
NUMTX, | ||
NUM_CLIENTS, | ||
mu_tx, | ||
mu_bal, | ||
sigma_tx, | ||
sigma_bal, | ||
tx_file_prefix, | ||
tx_file_suffix, | ||
bal_file_prefix, | ||
bal_file_suffix, | ||
NETTING_BASE_DIR, | ||
) | ||
|
||
|
||
def open_tx_files(): | ||
f = [] | ||
for i in range(0, NUM_CLIENTS): | ||
file = tx_file_prefix + str(i) + tx_file_suffix | ||
f.append(open(NETTING_BASE_DIR + "data/" + file, "a+")) | ||
return f | ||
|
||
|
||
def open_bal_files(): | ||
f = [] | ||
for i in range(0, NUM_CLIENTS): | ||
file = bal_file_prefix + str(i) + bal_file_suffix | ||
f.append(open(NETTING_BASE_DIR + "data/" + file, "a+")) | ||
return f | ||
|
||
|
||
def close_files(files): | ||
for f in files: | ||
f.close() | ||
|
||
|
||
def gen_data_files(): | ||
|
||
f = open_tx_files() | ||
|
||
for i in range(0, NUMTX): | ||
# sample random sender: Samples from 1 through to N | ||
sender = random.randint(0, NUM_CLIENTS - 1) | ||
|
||
# sample reciever such that it is different from sender | ||
reciever = None | ||
while True: | ||
reciever = random.randint(0, NUM_CLIENTS - 1) | ||
if sender != reciever: | ||
break | ||
|
||
# sample amount from a normal distribution | ||
amount = random.gauss(mu_tx, sigma_tx) | ||
# Add the tx to sender file | ||
f[sender].write( | ||
str(sender) | ||
+ "," | ||
+ str(reciever) | ||
+ "," | ||
+ str.format("{0:.2f}", amount) | ||
+ "\n" | ||
) | ||
# Add tx to reciever file | ||
f[reciever].write( | ||
str(sender) | ||
+ "," | ||
+ str(reciever) | ||
+ "," | ||
+ str.format("{0:.2f}", amount) | ||
+ "\n" | ||
) | ||
|
||
close_files(f) | ||
|
||
f = open_bal_files() | ||
|
||
for i in range(0, NUM_CLIENTS): | ||
f[i].write(str.format("{0:.2f}", random.gauss(mu_bal, sigma_bal)) + "\n") | ||
|
||
close_files(f) | ||
|
||
|
||
def clean_files(): | ||
path = NETTING_BASE_DIR + "data/" | ||
try: | ||
shutil.rmtree(path) | ||
except Exception as e: | ||
logging.exception(e) | ||
pass | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
os.makedirs(NETTING_BASE_DIR + "data") | ||
|
||
|
||
def main(): | ||
# clean data folder | ||
clean_files() | ||
# recreate all data | ||
gen_data_files() | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
""" | ||
Netting Client | ||
""" | ||
from apps.netting.config.config import ( | ||
NUM_CLIENTS, | ||
NETTING_BASE_DIR, | ||
tx_file_prefix, | ||
tx_file_suffix, | ||
bal_file_prefix, | ||
bal_file_suffix, | ||
) | ||
import logging | ||
|
||
|
||
class Transaction: | ||
|
||
""" | ||
Initalize the transaction from CSV file line. Currently this is the only | ||
way we take inputs. | ||
""" | ||
|
||
def __init__(self, csv_string): | ||
params = csv_string.split(",") | ||
assert len(params) == 3, "File transaction format incorrect" | ||
self.amount = int(float(params[2]) * 100) | ||
self.sender = int(params[0]) | ||
self.reciever = int(params[1]) | ||
|
||
|
||
def read_balance(id): | ||
ret = "" | ||
with open( | ||
NETTING_BASE_DIR + "data/" + bal_file_prefix + str(id) + bal_file_suffix, "r" | ||
) as f: | ||
for line in f.readlines(): | ||
ret = int(float(line) * 100) | ||
return ret | ||
|
||
|
||
def read_txs(id): | ||
in_tx = [] | ||
out_tx = [] | ||
with open( | ||
NETTING_BASE_DIR + "data/" + tx_file_prefix + str(id) + tx_file_suffix | ||
) as f: | ||
for line in f.readlines(): | ||
tx = Transaction(line) | ||
if tx.sender == id: | ||
out_tx.append(tx) | ||
elif tx.reciever == id: | ||
in_tx.append(tx) | ||
else: | ||
logging.execption( | ||
"Incorrect reading of file \ | ||
either or reicever must be the same as file id" | ||
) | ||
raise | ||
return (in_tx, out_tx) | ||
|
||
|
||
class Client: | ||
def __init__(self, id): | ||
self.id = id | ||
self.balance = read_balance(id) | ||
self.out_tx, self.in_tx = read_txs(id) | ||
|
||
|
||
def init_clients(): | ||
clients = [] | ||
for i in range(0, NUM_CLIENTS): | ||
clients.append(Client(i)) | ||
return clients | ||
|
||
|
||
if __name__ == "__main__": | ||
clients = init_clients() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import apps.netting.scripts.generate_data as data_gen | ||
|
||
import apps.netting.src.client as clients | ||
|
||
""" | ||
Test that everything is initilzed correctly for the application. | ||
""" | ||
|
||
|
||
def test_init(): | ||
data_gen.main() | ||
clis = clients.init_clients() | ||
|
||
for cli in clis: | ||
assert cli.balance >= 0, "Init balance >= 0" | ||
assert ( | ||
len(cli.out_tx) + len(cli.in_tx) >= 1 | ||
), "With high probability must have atleast one tx" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a plan to have more files under
apps/netting/config/
? If not,apps/netting/config.py
is sufficient and makes the code simpler.