mirror of
https://github.com/bigchaindb/bigchaindb.git
synced 2024-10-13 13:34:05 +00:00
Made AbstractConsensusRules use python's abc and enforcing that ConsensusRules plugins subclass it
This commit is contained in:
parent
01d706ac56
commit
14b71537d6
@ -41,9 +41,7 @@ config = {
|
||||
'rate': e('BIGCHAIN_STATSD_SAMPLERATE', default=0.01)
|
||||
},
|
||||
'api_endpoint': 'http://localhost:8008/api/v1',
|
||||
'consensus_plugins': [
|
||||
'base'
|
||||
]
|
||||
'consensus_plugin': e('BIGCHAIN_CONSENSUS_PLUGIN', default='default')
|
||||
}
|
||||
|
||||
# We need to maintain a backup copy of the original config dict in case
|
||||
|
@ -17,7 +17,7 @@ import json
|
||||
import logging
|
||||
import collections
|
||||
|
||||
from pkg_resources import iter_entry_points
|
||||
from pkg_resources import iter_entry_points, ResolutionError
|
||||
|
||||
import bigchaindb
|
||||
|
||||
@ -103,20 +103,37 @@ def autoconfigure():
|
||||
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', [])
|
||||
def load_consensus_plugin(name=None):
|
||||
"""Find and load the chosen consensus plugin.
|
||||
|
||||
plugins = []
|
||||
Args:
|
||||
name (string): the name of the entry_point, as advertised in the
|
||||
setup.py of the providing package.
|
||||
|
||||
# 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())
|
||||
Returns:
|
||||
an uninstantiated subclass of ``bigchaindb.consensus.AbstractConsensusRules``
|
||||
"""
|
||||
if not name:
|
||||
name = bigchaindb.config.get('consensus_plugin', 'default')
|
||||
|
||||
return plugins
|
||||
# TODO: This will return the first plugin with group `bigchaindb.plugins`
|
||||
# and name `name` in the active WorkingSet.
|
||||
# We should probably support Requirements specs in the config, e.g.
|
||||
# consensus_plugin: 'my-plugin-package==0.0.1;default'
|
||||
plugin = None
|
||||
for entry_point in iter_entry_points('bigchaindb.consensus', name):
|
||||
plugin = entry_point.load()
|
||||
|
||||
# No matching entry_point found
|
||||
if not plugin:
|
||||
raise ResolutionError(
|
||||
'No plugin found in group `bigchaindb.plugins` with name `{}`'.
|
||||
format(name))
|
||||
|
||||
# Is this strictness desireable?
|
||||
# It will probably reduce developer headaches in the wild.
|
||||
if not issubclass(plugin, (AbstractConsensusRules)):
|
||||
raise TypeError("object of type '{}' does not implement `bigchaindb."
|
||||
"consensus.AbstractConsensusRules`".format(type(plugin)))
|
||||
|
||||
return plugin
|
||||
|
@ -1,17 +1,21 @@
|
||||
from abc import ABCMeta, abstractmethod
|
||||
|
||||
import bigchaindb.exceptions as exceptions
|
||||
from bigchaindb import util
|
||||
from bigchaindb.crypto import hash_data
|
||||
from bigchaindb.crypto import hash_data, PublicKey
|
||||
|
||||
# TODO: no real reason to use abc yet, but later we can enforce inheritance from
|
||||
# this class when loading plugins if that's desirable.
|
||||
# from abc import ABCMeta
|
||||
|
||||
class AbstractConsensusRules:
|
||||
class AbstractConsensusRules(metaclass=ABCMeta):
|
||||
"""Abstract base class for Bigchain plugins which implement consensus logic.
|
||||
|
||||
# TODO: rather than having plugin-authors inherit and override,
|
||||
# it'd be cleaner to make a `transactionrule` decorator and etc
|
||||
@classmethod
|
||||
def validate_transaction(cls, bigchain, transaction):
|
||||
A consensus plugin must expose a class inheriting from this one via an
|
||||
entry_point.
|
||||
|
||||
All methods listed below must be implemented.
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def validate_transaction(bigchain, transaction):
|
||||
"""Validate a transaction.
|
||||
|
||||
Args:
|
||||
@ -26,10 +30,10 @@ class AbstractConsensusRules:
|
||||
Descriptive exceptions indicating the reason the transaction failed.
|
||||
See the `exceptions` module for bigchain-native error classes.
|
||||
"""
|
||||
return transaction
|
||||
raise NotImplementedError
|
||||
|
||||
@classmethod
|
||||
def validate_block(cls, bigchain, block):
|
||||
@abstractmethod
|
||||
def validate_block(bigchain, block):
|
||||
"""Validate a block.
|
||||
|
||||
Args:
|
||||
|
Loading…
x
Reference in New Issue
Block a user