Don't learn about nodes with a newer version than you.

pull/574/head
jMyles 2018-11-29 17:26:30 -05:00
parent c15408e775
commit 4c9f9108ed
4 changed files with 36 additions and 10 deletions

View File

@ -14,3 +14,4 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
"""
LEARNING_LOOP_VERSION = 1

View File

@ -47,6 +47,7 @@ from nucypher.config.storages import InMemoryNodeStorage
from nucypher.crypto.api import keccak_digest
from nucypher.crypto.powers import BlockchainPower, SigningPower, EncryptingPower, NoSigningPower
from nucypher.crypto.signing import signature_splitter
from nucypher.network import LEARNING_LOOP_VERSION
from nucypher.network.middleware import RestMiddleware
from nucypher.network.nicknames import nickname_from_seed
from nucypher.network.protocols import SuspiciousActivity
@ -203,6 +204,10 @@ class Learner:
__DEFAULT_NODE_STORAGE = InMemoryNodeStorage
__DEFAULT_MIDDLEWARE_CLASS = RestMiddleware
LEARNER_VERSION = LEARNING_LOOP_VERSION
node_splitter = BytestringSplitter(VariableLengthBytestring)
version_splitter = BytestringSplitter((int, 2, {"byteorder": "big"}))
class NotEnoughTeachers(RuntimeError):
pass
@ -692,7 +697,7 @@ class Learner:
class Teacher:
TEACHER_VERSION = 1
TEACHER_VERSION = LEARNING_LOOP_VERSION
verified_stamp = False
verified_interface = False
_verified_node = False
@ -837,14 +842,17 @@ class Teacher:
if not response.status_code == 200:
raise RuntimeError("Or something.") # TODO: Raise an error here? Or return False? Or something?
timestamp, signature, identity_evidence, \
verifying_key, encrypting_key, \
public_address, certificate_vbytes, rest_info = self._internal_splitter(response.content)
verifying_keys_match = verifying_key == self.public_keys(SigningPower)
encrypting_keys_match = encrypting_key == self.public_keys(EncryptingPower)
addresses_match = public_address == self.canonical_public_address
evidence_matches = identity_evidence == self._evidence_of_decentralized_identity
version, node_bytes = self.version_splitter(response.content, return_remainder=True)
if version > self.LEARNER_VERSION:
raise ValueError("Something") # TODO: Properly handle this.
else:
node_details = self.internal_splitter(node_bytes)
verifying_keys_match = node_details['verifying_key'] == self.public_keys(SigningPower)
encrypting_keys_match = node_details['encrypting_key'] == self.public_keys(EncryptingPower)
addresses_match = node_details['public_address'] == self.canonical_public_address
evidence_matches = node_details['identity_evidence'] == self._evidence_of_decentralized_identity
if not all((encrypting_keys_match, verifying_keys_match, addresses_match, evidence_matches)):
# TODO: Optional reporting. 355

View File

@ -36,6 +36,7 @@ from nucypher.crypto.signing import InvalidSignature
from nucypher.keystore.keypairs import HostingKeypair
from nucypher.keystore.keystore import NotFound
from nucypher.keystore.threading import ThreadedSession
from nucypher.network import LEARNING_LOOP_VERSION
from nucypher.network.protocols import InterfaceInfo
from jinja2 import Template
@ -45,6 +46,7 @@ TEMPLATES_DIR = os.path.join(HERE, "templates")
class ProxyRESTServer:
log = Logger("characters")
SERVER_VERSION = LEARNING_LOOP_VERSION
def __init__(self,
rest_host: str,

View File

@ -1,2 +1,17 @@
def teat_learn_but_nodes_are_already_run(federated_ursulas):
assert False
from functools import partial
from nucypher.utilities.sandbox.ursula import make_federated_ursulas
def test_emit_warning_upon_new_version(ursula_federated_test_config, caplog):
lonely_ursula_maker = partial(make_federated_ursulas,
ursula_config=ursula_federated_test_config,
quantity=2,
know_each_other=True)
learner = lonely_ursula_maker().pop()
teacher, new_node = lonely_ursula_maker()
new_node.TEACHER_VERSION = learner.LEARNER_VERSION + 1
learner._current_teacher_node = teacher
learner.learn_from_teacher_node()