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)
|
'rate': e('BIGCHAIN_STATSD_SAMPLERATE', default=0.01)
|
||||||
},
|
},
|
||||||
'api_endpoint': 'http://localhost:8008/api/v1',
|
'api_endpoint': 'http://localhost:8008/api/v1',
|
||||||
'consensus_plugins': [
|
'consensus_plugin': e('BIGCHAIN_CONSENSUS_PLUGIN', default='default')
|
||||||
'base'
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# We need to maintain a backup copy of the original config dict in case
|
# We need to maintain a backup copy of the original config dict in case
|
||||||
|
@ -17,7 +17,7 @@ import json
|
|||||||
import logging
|
import logging
|
||||||
import collections
|
import collections
|
||||||
|
|
||||||
from pkg_resources import iter_entry_points
|
from pkg_resources import iter_entry_points, ResolutionError
|
||||||
|
|
||||||
import bigchaindb
|
import bigchaindb
|
||||||
|
|
||||||
@ -103,20 +103,37 @@ def autoconfigure():
|
|||||||
logger.warning('Cannot find your config file. Run `bigchaindb configure` to create one')
|
logger.warning('Cannot find your config file. Run `bigchaindb configure` to create one')
|
||||||
|
|
||||||
|
|
||||||
def get_plugins(plugin_names):
|
def load_consensus_plugin(name=None):
|
||||||
if not plugin_names:
|
"""Find and load the chosen consensus plugin.
|
||||||
plugin_names = bigchaindb.config.get('consensus_plugins', [])
|
|
||||||
|
|
||||||
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.
|
Returns:
|
||||||
# e.g. Expensive validation tasks should happen after cheap ones.
|
an uninstantiated subclass of ``bigchaindb.consensus.AbstractConsensusRules``
|
||||||
#
|
"""
|
||||||
# TODO: We might want to add some sort of priority system, but for now we
|
if not name:
|
||||||
# simply assume everything in a given plugin is designed to run at the
|
name = bigchaindb.config.get('consensus_plugin', 'default')
|
||||||
# same time.
|
|
||||||
for name in plugin_names:
|
|
||||||
for entry_point in iter_entry_points('bigchaindb.plugins', name):
|
|
||||||
plugins.append(entry_point.load())
|
|
||||||
|
|
||||||
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
|
import bigchaindb.exceptions as exceptions
|
||||||
from bigchaindb import util
|
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,
|
A consensus plugin must expose a class inheriting from this one via an
|
||||||
# it'd be cleaner to make a `transactionrule` decorator and etc
|
entry_point.
|
||||||
@classmethod
|
|
||||||
def validate_transaction(cls, bigchain, transaction):
|
All methods listed below must be implemented.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def validate_transaction(bigchain, transaction):
|
||||||
"""Validate a transaction.
|
"""Validate a transaction.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -26,10 +30,10 @@ class AbstractConsensusRules:
|
|||||||
Descriptive exceptions indicating the reason the transaction failed.
|
Descriptive exceptions indicating the reason the transaction failed.
|
||||||
See the `exceptions` module for bigchain-native error classes.
|
See the `exceptions` module for bigchain-native error classes.
|
||||||
"""
|
"""
|
||||||
return transaction
|
raise NotImplementedError
|
||||||
|
|
||||||
@classmethod
|
@abstractmethod
|
||||||
def validate_block(cls, bigchain, block):
|
def validate_block(bigchain, block):
|
||||||
"""Validate a block.
|
"""Validate a block.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user