From b1c2c6e3a220c6074a9189433fa04507fed3e00b Mon Sep 17 00:00:00 2001 From: protolambda Date: Mon, 11 May 2020 19:18:49 +0200 Subject: [PATCH] Default BLS to ON, keep CI BLS off for now, add milagro option --- Makefile | 6 ++-- setup.py | 1 + tests/core/pyspec/README.md | 5 +++ tests/core/pyspec/eth2spec/test/conftest.py | 35 ++++++++++++++++++--- tests/core/pyspec/eth2spec/test/context.py | 5 +-- tests/core/pyspec/eth2spec/utils/bls.py | 17 +++++++--- 6 files changed, 55 insertions(+), 14 deletions(-) diff --git a/Makefile b/Makefile index e53aaf8a2..f52ef050d 100644 --- a/Makefile +++ b/Makefile @@ -75,15 +75,15 @@ install_test: test: pyspec . venv/bin/activate; cd $(PY_SPEC_DIR); \ - python -m pytest -n 4 --cov=eth2spec.phase0.spec --cov=eth2spec.phase1.spec --cov-report="html:$(COV_HTML_OUT)" --cov-branch eth2spec + python -m pytest -n 4 --disable-bls --cov=eth2spec.phase0.spec --cov=eth2spec.phase1.spec --cov-report="html:$(COV_HTML_OUT)" --cov-branch eth2spec find_test: pyspec . venv/bin/activate; cd $(PY_SPEC_DIR); \ - python -m pytest -k=$(K) --cov=eth2spec.phase0.spec --cov=eth2spec.phase1.spec --cov-report="html:$(COV_HTML_OUT)" --cov-branch eth2spec + python -m pytest -k=$(K) --disable-bls --cov=eth2spec.phase0.spec --cov=eth2spec.phase1.spec --cov-report="html:$(COV_HTML_OUT)" --cov-branch eth2spec citest: pyspec mkdir -p tests/core/pyspec/test-reports/eth2spec; . venv/bin/activate; cd $(PY_SPEC_DIR); \ - python -m pytest -n 4 --junitxml=eth2spec/test_results.xml eth2spec + python -m pytest -n 4 --disable-bls --junitxml=eth2spec/test_results.xml eth2spec open_cov: ((open "$(COV_INDEX_FILE)" || xdg-open "$(COV_INDEX_FILE)") &> /dev/null) & diff --git a/setup.py b/setup.py index 37f3c16ef..16ae6ac5c 100644 --- a/setup.py +++ b/setup.py @@ -502,6 +502,7 @@ setup( "eth-typing>=2.1.0,<3.0.0", "pycryptodome==3.9.4", "py_ecc==2.0.0", + "milagro_bls_binding==1.0.2", "dataclasses==0.6", "remerkleable==0.1.13", "ruamel.yaml==0.16.5", diff --git a/tests/core/pyspec/README.md b/tests/core/pyspec/README.md index a9ee80105..f7092dbce 100644 --- a/tests/core/pyspec/README.md +++ b/tests/core/pyspec/README.md @@ -55,6 +55,11 @@ Run the test command from the `tests/core/pyspec` directory: pytest --config=minimal eth2spec ``` +Options: +- `--config`, to change the config. Defaults to `minimal`, can be set to `mainnet`, or other configs from the configs directory. +- `--disable-bls`, to disable BLS (only for tests that can run without) +- `--bls-type`, `milagro` or `py_ecc` (default) + ### How to view code coverage report Run `make open_cov` from the root of the specs repository after running `make test` to open the html code coverage report. diff --git a/tests/core/pyspec/eth2spec/test/conftest.py b/tests/core/pyspec/eth2spec/test/conftest.py index 01187b05f..01c974ae0 100644 --- a/tests/core/pyspec/eth2spec/test/conftest.py +++ b/tests/core/pyspec/eth2spec/test/conftest.py @@ -1,6 +1,6 @@ from eth2spec.config import config_util -from eth2spec.test.context import reload_specs - +from eth2spec.test import context +from eth2spec.utils import bls as bls_utils # We import pytest only when it's present, i.e. when we are running tests. # The test-cases themselves can be generated without installing pytest. @@ -27,7 +27,16 @@ def fixture(*args, **kwargs): def pytest_addoption(parser): parser.addoption( - "--config", action="store", default="minimal", help="config: make the pyspec use the specified configuration" + "--config", action="store", type=str, default="minimal", + help="config: make the pyspec use the specified configuration" + ) + parser.addoption( + "--disable-bls", action="store_true", + help="bls-default: make tests that are not dependent on BLS run without BLS" + ) + parser.addoption( + "--bls-type", action="store", type=str, default="py_ecc", choices=["py_ecc", "milagro"], + help="bls-type: use 'pyecc' or 'milagro' implementation for BLS" ) @@ -36,4 +45,22 @@ def config(request): config_name = request.config.getoption("--config") config_util.prepare_config('../../../configs/', config_name) # now that the presets are loaded, reload the specs to apply them - reload_specs() + context.reload_specs() + + +@fixture(autouse=True) +def bls_default(request): + disable_bls = request.config.getoption("--disable-bls") + if disable_bls: + context.DEFAULT_BLS_ACTIVE = False + + +@fixture(autouse=True) +def bls_type(request): + bls_type = request.config.getoption("--bls-type") + if bls_type == "py_ecc": + bls_utils.bls = bls_utils.py_ecc_bls + elif bls_type == "milagro": + bls_utils.bls = bls_utils.milagro_bls + else: + raise Exception(f"unrecognized bls type: {bls_type}") diff --git a/tests/core/pyspec/eth2spec/test/context.py b/tests/core/pyspec/eth2spec/test/context.py index 1a182fd31..1108edcf7 100644 --- a/tests/core/pyspec/eth2spec/test/context.py +++ b/tests/core/pyspec/eth2spec/test/context.py @@ -147,14 +147,15 @@ def single_phase(fn): return entry -# BLS is turned off by default *for performance purposes during TESTING*. +# BLS is turned on by default, it can be disabled in tests by overriding this, or using `--disable-bls`. +# *This is for performance purposes during TESTING, DO NOT DISABLE IN PRODUCTION*. # The runner of the test can indicate the preferred setting (test generators prefer BLS to be ON). # - Some tests are marked as BLS-requiring, and ignore this setting. # (tests that express differences caused by BLS, e.g. invalid signatures being rejected) # - Some other tests are marked as BLS-ignoring, and ignore this setting. # (tests that are heavily performance impacted / require unsigned state transitions) # - Most tests respect the BLS setting. -DEFAULT_BLS_ACTIVE = False +DEFAULT_BLS_ACTIVE = True def spec_test(fn): diff --git a/tests/core/pyspec/eth2spec/utils/bls.py b/tests/core/pyspec/eth2spec/utils/bls.py index 3b648fac9..44d0a8012 100644 --- a/tests/core/pyspec/eth2spec/utils/bls.py +++ b/tests/core/pyspec/eth2spec/utils/bls.py @@ -1,9 +1,13 @@ -from py_ecc.bls import G2ProofOfPossession as bls +from py_ecc.bls import G2ProofOfPossession as py_ecc_bls from py_ecc.bls.g2_primatives import signature_to_G2 as _signature_to_G2 +import milagro_bls_binding as milagro_bls # noqa: F401 for BLS switching option # Flag to make BLS active or not. Used for testing, do not ignore BLS in production unless you know what you are doing. bls_active = True +# To change bls implementation, default to PyECC for correctness. Milagro is a good faster alternative. +bls = py_ecc_bls + STUB_SIGNATURE = b'\x11' * 96 STUB_PUBKEY = b'\x22' * 48 STUB_COORDINATES = _signature_to_G2(bls.Sign(0, b"")) @@ -30,12 +34,12 @@ def Verify(PK, message, signature): @only_with_bls(alt_return=True) def AggregateVerify(pairs, signature): - return bls.AggregateVerify(pairs, signature) + return bls.AggregateVerify(list(pairs), signature) @only_with_bls(alt_return=True) def FastAggregateVerify(PKs, message, signature): - return bls.FastAggregateVerify(PKs, message, signature) + return bls.FastAggregateVerify(list(PKs), message, signature) @only_with_bls(alt_return=STUB_SIGNATURE) @@ -45,7 +49,10 @@ def Aggregate(signatures): @only_with_bls(alt_return=STUB_SIGNATURE) def Sign(SK, message): - return bls.Sign(SK, message) + if bls == py_ecc_bls: + return bls.Sign(SK, message) + else: + return bls.Sign(SK.to_bytes(48, 'big'), message) @only_with_bls(alt_return=STUB_COORDINATES) @@ -55,4 +62,4 @@ def signature_to_G2(signature): @only_with_bls(alt_return=STUB_PUBKEY) def AggregatePKs(pubkeys): - return bls._AggregatePKs(pubkeys) + return bls._AggregatePKs(list(pubkeys))