From 8a9030e5c0269d989221446d1e3ec8f105a2df9c Mon Sep 17 00:00:00 2001 From: Matt Smith Date: Mon, 29 Feb 2016 18:38:33 -0800 Subject: [PATCH] Added a simple plugin system for consensus rules using setuputils entry_points --- bigchaindb/__init__.py | 5 ++++- bigchaindb/config_utils.py | 20 ++++++++++++++++++++ bigchaindb/consensus/__init__.py | 0 bigchaindb/core.py | 4 +++- setup.py | 10 +++++++++- 5 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 bigchaindb/consensus/__init__.py diff --git a/bigchaindb/__init__.py b/bigchaindb/__init__.py index 4bb76c44..b728e103 100644 --- a/bigchaindb/__init__.py +++ b/bigchaindb/__init__.py @@ -39,7 +39,10 @@ config = { 'host': e('BIGCHAIN_STATSD_HOST', default='localhost'), 'port': e('BIGCHAIN_STATSD_PORT', default=8125), 'rate': e('BIGCHAIN_STATSD_SAMPLERATE', default=0.01) - } + }, + 'consensus_plugins': [ + 'base' + ], } # We need to maintain a backup copy of the original config dict in case diff --git a/bigchaindb/config_utils.py b/bigchaindb/config_utils.py index bf3ed529..c273245d 100644 --- a/bigchaindb/config_utils.py +++ b/bigchaindb/config_utils.py @@ -17,6 +17,8 @@ import json import logging import collections +from pkg_resources import iter_entry_points + import bigchaindb logger = logging.getLogger(__name__) @@ -100,3 +102,21 @@ def autoconfigure(): except FileNotFoundError: logger.warning('Cannot find your config file. Run `bigchaindb configure` to create one') + +def get_plugins(plugin_names): + if not plugin_names: + plugin_names = bigchaindb.config.get('consensus_plugins', []) + + plugins = [] + + # It's important to maintain plugin ordering as stated in the config file. + # e.g. Expensive validation tasks should happen after cheap ones. + # + # TODO: We might want to add some sort of priority system, but for now we + # simply assume everything in a given plugin is designed to run at the + # same time. + for name in plugin_names: + for entry_point in iter_entry_points('bigchaindb.plugins', name): + plugins.append(entry_point.load()) + + return plugins diff --git a/bigchaindb/consensus/__init__.py b/bigchaindb/consensus/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/bigchaindb/core.py b/bigchaindb/core.py index f2ba61dd..89cccd7e 100644 --- a/bigchaindb/core.py +++ b/bigchaindb/core.py @@ -30,7 +30,8 @@ class Bigchain(object): """ def __init__(self, host=None, port=None, dbname=None, - public_key=None, private_key=None, keyring=[]): + public_key=None, private_key=None, keyring=[], + consensus_plugins=['base']): """Initialize the Bigchain instance There are three ways in which the Bigchain instance can get its parameters. @@ -56,6 +57,7 @@ class Bigchain(object): self.me = public_key or bigchaindb.config['keypair']['public'] self.me_private = private_key or bigchaindb.config['keypair']['private'] self.federation_nodes = keyring or bigchaindb.config['keyring'] + self.consensus_plugins = config_utils.get_plugins(consensus_plugins) if not self.me or not self.me_private: raise KeypairNotFoundException() diff --git a/setup.py b/setup.py index 3fd8dae4..26f111fa 100644 --- a/setup.py +++ b/setup.py @@ -54,13 +54,21 @@ setup( 'Operating System :: POSIX :: Linux', ], - packages=['bigchaindb', 'bigchaindb.commands', 'bigchaindb.db'], + packages=[ + 'bigchaindb', + 'bigchaindb.commands', + 'bigchaindb.db', + 'bigchaindb.consensus' + ], entry_points={ 'console_scripts': [ 'bigchaindb=bigchaindb.commands.bigchain:main', 'bigchaindb-benchmark=bigchaindb.commands.bigchain_benchmark:main' ], + 'bigchaindb.plugins': [ + 'base=bigchaindb.consensus.base:ConsensusRules' + ] }, install_requires=[ 'rethinkdb==2.2.0.post4',