def test_create_wait_certificate_with_wrong_wait_timer(self): # Need to create signup information SignupInfo.create_signup_info( validator_address='1660 Pennsylvania Avenue NW', originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id=NullIdentifier) # Create two timers and try to create the wait certificate with the # first one, which should fail as it is not the current wait timer invalid_wt = \ WaitTimer.create_wait_timer( validator_address='1660 Pennsylvania Avenue NW', certificates=[]) valid_wt = \ WaitTimer.create_wait_timer( validator_address='1660 Pennsylvania Avenue NW', certificates=[]) # Verify that we cannot create a wait certificate with the old wait # timer, but we can with the new one with self.assertRaises(ValueError): WaitCertificate.create_wait_certificate( wait_timer=invalid_wt, block_digest="Reader's Digest") WaitCertificate.create_wait_certificate(wait_timer=valid_wt, block_digest="Reader's Digest")
def test_create_wait_certificate_after_wait_timer_timed_out(self): # Need to create signup information SignupInfo.create_signup_info( validator_address='1660 Pennsylvania Avenue NW', originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id=NullIdentifier) # Create a wait certificate for the genesis block so that we can # create another wait certificate that has to play by the rules. wt = \ WaitTimer.create_wait_timer( validator_address='1660 Pennsylvania Avenue NW', certificates=[]) wc = \ WaitCertificate.create_wait_certificate( wait_timer=wt, block_digest="Reader's Digest") wt = \ WaitTimer.create_wait_timer( validator_address='1660 Pennsylvania Avenue NW', certificates=[wc]) while not wt.has_expired(time.time()): time.sleep(1) time.sleep(WaitTimer.poet_enclave.TIMER_TIMEOUT_PERIOD + 1) with self.assertRaises(ValueError): WaitCertificate.create_wait_certificate( wait_timer=wt, block_digest="Reader's Digest")
def test_create_wait_certificate_before_wait_timer_expires(self): # Need to create signup information SignupInfo.create_signup_info( validator_address='1660 Pennsylvania Avenue NW', originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id=NullIdentifier) # Create a wait certificate for the genesis block so that we can # create another wait certificate that has to play by the rules. wt = \ WaitTimer.create_wait_timer( validator_address='1660 Pennsylvania Avenue NW', certificates=[]) wc = \ WaitCertificate.create_wait_certificate( wait_timer=wt, block_digest="Reader's Digest") wt = \ WaitTimer.create_wait_timer( validator_address='1660 Pennsylvania Avenue NW', certificates=[wc]) with self.assertRaises(ValueError): WaitCertificate.create_wait_certificate( wait_timer=wt, block_digest="Reader's Digest")
def test_create_wait_certificate_with_wrong_wait_timer(self): # Need to create signup information SignupInfo.create_signup_info( validator_address='1660 Pennsylvania Avenue NW', originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id=NullIdentifier) # Create two timers and try to create the wait certificate with the # first one, which should fail as it is not the current wait timer invalid_wt = \ WaitTimer.create_wait_timer( validator_address='1660 Pennsylvania Avenue NW', certificates=[]) valid_wt = \ WaitTimer.create_wait_timer( validator_address='1660 Pennsylvania Avenue NW', certificates=[]) # Verify that we cannot create a wait certificate with the old wait # timer, but we can with the new one with self.assertRaises(ValueError): WaitCertificate.create_wait_certificate( wait_timer=invalid_wt, block_digest="Reader's Digest") WaitCertificate.create_wait_certificate( wait_timer=valid_wt, block_digest="Reader's Digest")
def test_create_wait_certificate_before_create_wait_timer(self): # Need to create signup information SignupInfo.create_signup_info( originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id=NullIdentifier) with self.assertRaises(WaitCertificateError): WaitCertificate.create_wait_certificate("Reader's Digest")
def test_create_wait_certificate_before_create_wait_timer(self): # Need to create signup information SignupInfo.create_signup_info( validator_address='1660 Pennsylvania Avenue NW', originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id=NullIdentifier) with self.assertRaises(ValueError): WaitCertificate.create_wait_certificate( wait_timer=None, block_digest="Reader's Digest")
def test_verify_unsealing_data(self): signup_info = \ SignupInfo.create_signup_info( originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id=NullIdentifier) poet_public_key = \ SignupInfo.unseal_signup_data(signup_info.sealed_signup_data) self.assertEqual( signup_info.poet_public_key, poet_public_key, msg="PoET public key in signup info and sealed data don't match")
def test_create_wait_certificate_before_create_wait_timer(self): # Need to create signup information SignupInfo.create_signup_info( validator_address='1660 Pennsylvania Avenue NW', originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id=NullIdentifier) # Make sure that trying to create a wait certificate before creating # a wait timer causes an error with self.assertRaises(ValueError): WaitCertificate.create_wait_certificate( wait_timer=None, block_digest="Reader's Digest")
def test_verify_serialized_signup_info(self): signup_info = \ SignupInfo.create_signup_info( originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id=NullIdentifier) serialized = signup_info.serialize() copy_signup_info = SignupInfo.signup_info_from_serialized(serialized) self.assertEqual(signup_info.poet_public_key, copy_signup_info.poet_public_key) self.assertEqual(signup_info.proof_data, copy_signup_info.proof_data) self.assertEqual(signup_info.anti_sybil_id, copy_signup_info.anti_sybil_id) self.assertIsNone(copy_signup_info.sealed_signup_data)
def test_create_wait_certificate_before_wait_timer_expires(self): # Need to create signup information SignupInfo.create_signup_info( originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id=NullIdentifier) # Create a wait certificate for the genesis block so that we can # create another wait certificate that has to play by the rules. wt = WaitTimer.create_wait_timer([]) wc = WaitCertificate.create_wait_certificate("Reader's Digest") wt = WaitTimer.create_wait_timer([wc]) with self.assertRaises(WaitCertificateError): wc = WaitCertificate.create_wait_certificate("Reader's Digest")
def test_has_expired(self): # Need to create signup information first SignupInfo.create_signup_info( validator_address='1660 Pennsylvania Avenue NW', originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id=NullIdentifier) # Verify that a timer doesn't expire before its creation time wt = wait_timer.WaitTimer.create_wait_timer( validator_address='1060 W Addison Street', certificates=[]) self.assertFalse(wt.has_expired(wt.request_time - 1)) # Create a timer and when it has expired, verify that the duration is # not greater than actual elapsed time. wt = wait_timer.WaitTimer.create_wait_timer( validator_address='1060 W Addison Street', certificates=[]) while not wt.has_expired(time.time()): time.sleep(1) self.assertLessEqual(wt.duration, time.time() - wt.request_time) # Tampering with the duration should not affect wait timer expiration wt = wait_timer.WaitTimer.create_wait_timer( validator_address='1060 W Addison Street', certificates=[]) assigned_duration = wt.duration wt.duration = 0 while not wt.has_expired(time.time()): time.sleep(1) self.assertLessEqual(assigned_duration, time.time() - wt.request_time) # Tampering with the request time should not affect wait timer # expiration wt = wait_timer.WaitTimer.create_wait_timer( validator_address='1060 W Addison Street', certificates=[]) assigned_request_time = wt.request_time wt.request_time -= wt.duration while not wt.has_expired(time.time()): time.sleep(1) self.assertLessEqual(wt.duration, time.time() - assigned_request_time)
def test_verify_unsealing_data(self): signup_info = \ SignupInfo.create_signup_info( validator_address='1660 Pennsylvania Avenue NW', originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id=NullIdentifier) poet_public_key = \ SignupInfo.unseal_signup_data( validator_address='1660 Pennsylvania Avenue NW', sealed_signup_data=signup_info.sealed_signup_data) self.assertEqual( signup_info.poet_public_key, poet_public_key, msg="PoET public key in signup info and sealed data don't match")
def test_register_validator_re_register(self): key = signed_object.generate_signing_key() public_key_hash = \ hashlib.sha256( signing.encode_pubkey( signing.generate_pubkey(key), 'hex')).hexdigest() validator_id = signed_object.generate_identifier(key) name = 'DasValidator' signup_info = \ SignupInfo.create_signup_info( originator_public_key_hash=public_key_hash, most_recent_wait_certificate_id='0' * 16) store = ObjectStore() transaction = \ ValidatorRegistryTransaction.register_validator( name, validator_id, signup_info) transaction.sign_object(key) try: transaction.check_valid(store) transaction.apply(store) except InvalidTransactionError as e: self.fail('Failed valid transaction: {}'.format(e)) try: # check if valid to register again transaction.check_valid(store) except InvalidTransactionError as e: self.fail('Failure: Double registered validator: {}'.format(e))
def test_register_validator_key_mismatch(self): key = signed_object.generate_signing_key() public_key_hash = \ hashlib.sha256( signing.encode_pubkey( signing.generate_pubkey(key), 'hex').encode()).hexdigest() key2 = signed_object.generate_signing_key() validator_id = signed_object.generate_identifier(key) name = 'DasValidator' signup_info = \ SignupInfo.create_signup_info( validator_address='1660 Pennsylvania Avenue NW', originator_public_key_hash=public_key_hash, most_recent_wait_certificate_id='0' * 16) store = ObjectStore() transaction = \ ValidatorRegistryTransaction.register_validator( name, validator_id, signup_info) transaction.sign_object(key2) with self.assertRaises(InvalidTransactionError): transaction.check_valid(store) self.fail("Failure: Verified an invalid transaction")
def test_register_validator_re_register(self): key = signed_object.generate_signing_key() public_key_hash = \ hashlib.sha256( signing.encode_pubkey( signing.generate_pubkey(key), 'hex').encode()).hexdigest() validator_id = signed_object.generate_identifier(key) name = 'DasValidator' signup_info = \ SignupInfo.create_signup_info( validator_address='1660 Pennsylvania Avenue NW', originator_public_key_hash=public_key_hash, most_recent_wait_certificate_id='0' * 16) store = ObjectStore() transaction = \ ValidatorRegistryTransaction.register_validator( name, validator_id, signup_info) transaction.sign_object(key) try: transaction.check_valid(store) transaction.apply(store) except InvalidTransactionError as e: self.fail('Failed valid transaction: {}'.format(e)) try: # check if valid to register again transaction.check_valid(store) except InvalidTransactionError as e: self.fail('Failure: Double registered validator: {}'.format(e))
def test_register_validator_key_mismatch(self): key = signed_object.generate_signing_key() public_key_hash = \ hashlib.sha256( signing.encode_pubkey( signing.generate_pubkey(key), 'hex')).hexdigest() key2 = signed_object.generate_signing_key() validator_id = signed_object.generate_identifier(key) name = 'DasValidator' signup_info = \ SignupInfo.create_signup_info( originator_public_key_hash=public_key_hash, most_recent_wait_certificate_id='0' * 16) store = ObjectStore() transaction = \ ValidatorRegistryTransaction.register_validator( name, validator_id, signup_info) transaction.sign_object(key2) with self.assertRaises(InvalidTransactionError): transaction.check_valid(store) self.fail("Failure: Verified an invalid transaction")
def test_verify_serialized_signup_info(self): signup_info = \ SignupInfo.create_signup_info( validator_address='1660 Pennsylvania Avenue NW', originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id=NullIdentifier) serialized = signup_info.serialize() copy_signup_info = SignupInfo.signup_info_from_serialized(serialized) self.assertEqual( signup_info.poet_public_key, copy_signup_info.poet_public_key) self.assertEqual(signup_info.proof_data, copy_signup_info.proof_data) self.assertEqual( signup_info.anti_sybil_id, copy_signup_info.anti_sybil_id) self.assertIsNone(copy_signup_info.sealed_signup_data)
def test_wait_certificate_serialization(self): # Need to create signup information and wait timer first signup_info = \ SignupInfo.create_signup_info( validator_address='1660 Pennsylvania Avenue NW', originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id=NullIdentifier) wt = \ WaitTimer.create_wait_timer( validator_address='1660 Pennsylvania Avenue NW', certificates=[]) while not wt.has_expired(time.time()): time.sleep(1) # Now we can create a wait certificate and serialize wc = \ WaitCertificate.create_wait_certificate( wait_timer=None, block_digest="Reader's Digest") dumped = wc.dump() self.assertIsNotNone(dumped.get('SerializedCertificate')) self.assertIsNotNone(dumped.get('Signature')) # Deserialize and verify that wait certificates are the same # and that deserialized one is valid wc_copy = \ WaitCertificate.wait_certificate_from_serialized( dumped.get('SerializedCertificate'), dumped.get('Signature')) self.assertEquals( wc.previous_certificate_id, wc_copy.previous_certificate_id) self.assertAlmostEquals(wc.local_mean, wc_copy.local_mean) self.assertAlmostEquals(wc.request_time, wc_copy.request_time) self.assertAlmostEquals(wc.duration, wc_copy.duration) self.assertEqual(wc.validator_address, wc_copy.validator_address) self.assertEqual(wc.block_digest, wc_copy.block_digest) self.assertEqual(wc.signature, wc_copy.signature) self.assertEqual(wc.identifier, wc_copy.identifier) # Serialize the copy and verify that its serialization and # signature are the same dumped_copy = wc_copy.dump() self.assertTrue( dumped.get('SerializedCertificate'), dumped_copy.get('SerializedCertificate')) self.assertTrue( dumped.get('Signature'), dumped_copy.get('Signature')) self.assertTrue(wc_copy.is_valid([], signup_info.poet_public_key))
def test_wait_certificate_serialization(self): # Need to create signup information and wait timer first signup_info = \ SignupInfo.create_signup_info( validator_address='1660 Pennsylvania Avenue NW', originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id=NullIdentifier) wt = \ WaitTimer.create_wait_timer( validator_address='1660 Pennsylvania Avenue NW', certificates=[]) while not wt.has_expired(time.time()): time.sleep(1) # Now we can create a wait certificate and serialize wc = \ WaitCertificate.create_wait_certificate( wait_timer=wt, block_digest="Reader's Digest") dumped = wc.dump() self.assertIsNotNone(dumped.get('SerializedCertificate')) self.assertIsNotNone(dumped.get('Signature')) # Deserialize and verify that wait certificates are the same # and that deserialized one is valid wc_copy = \ WaitCertificate.wait_certificate_from_serialized( dumped.get('SerializedCertificate'), dumped.get('Signature')) self.assertEqual( wc.previous_certificate_id, wc_copy.previous_certificate_id) self.assertAlmostEqual(wc.local_mean, wc_copy.local_mean) self.assertAlmostEqual(wc.request_time, wc_copy.request_time) self.assertAlmostEqual(wc.duration, wc_copy.duration) self.assertEqual(wc.validator_address, wc_copy.validator_address) self.assertEqual(wc.block_digest, wc_copy.block_digest) self.assertEqual(wc.signature, wc_copy.signature) self.assertEqual(wc.identifier, wc_copy.identifier) # Serialize the copy and verify that its serialization and # signature are the same dumped_copy = wc_copy.dump() self.assertTrue( dumped.get('SerializedCertificate'), dumped_copy.get('SerializedCertificate')) self.assertTrue( dumped.get('Signature'), dumped_copy.get('Signature')) wc_copy.check_valid([], signup_info.poet_public_key)
def test_basic_create_signup_info(self): signup_info = \ SignupInfo.create_signup_info( originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id=NullIdentifier) self.assertIsNotNone(signup_info.poet_public_key) self.assertIsNotNone(signup_info.proof_data) self.assertIsNotNone(signup_info.anti_sybil_id) self.assertIsNotNone(signup_info.sealed_signup_data)
def test_create_wait_certificate_with_reused_wait_timer(self): # Need to create signup information SignupInfo.create_signup_info( validator_address='1660 Pennsylvania Avenue NW', originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id=NullIdentifier) # Create a wait certificate for the genesis block so that we can # create another wait certificate that has to play by the rules. wt = \ WaitTimer.create_wait_timer( validator_address='1660 Pennsylvania Avenue NW', certificates=[]) wc = \ WaitCertificate.create_wait_certificate( wait_timer=wt, block_digest="Reader's Digest") consumed_wt = wt # Verify that we cannot use the consumed wait timer to create a wait # certificate either before or after creating a new wait timer with self.assertRaises(ValueError): WaitCertificate.create_wait_certificate( wait_timer=consumed_wt, block_digest="Reader's Digest") wt = \ WaitTimer.create_wait_timer( validator_address='1660 Pennsylvania Avenue NW', certificates=[wc]) with self.assertRaises(ValueError): WaitCertificate.create_wait_certificate( wait_timer=consumed_wt, block_digest="Reader's Digest") # Verify that once the new timer expires, we can create a wait # certificate with it while not wt.has_expired(time.time()): time.sleep(1) WaitCertificate.create_wait_certificate( wait_timer=wt, block_digest="Reader's Digest")
def test_non_matching_originator_public_key(self): signup_info = \ SignupInfo.create_signup_info( originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id=NullIdentifier) with self.assertRaises(SignupInfoError): signup_info.check_valid( originator_public_key_hash=self._another_public_key_hash, most_recent_wait_certificate_id=NullIdentifier)
def test_create_wait_certificate(self): # Need to create signup information and wait timer first signup_info = \ SignupInfo.create_signup_info( validator_address='1660 Pennsylvania Avenue NW', originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id=NullIdentifier) wt = \ WaitTimer.create_wait_timer( validator_address='1660 Pennsylvania Avenue NW', certificates=[]) while not wt.has_expired(time.time()): time.sleep(1) # Now we can create a wait certificate and verify that it correlates # to the wait timer we just created wc = \ WaitCertificate.create_wait_certificate( wait_timer=None, block_digest="Reader's Digest") self.assertIsNotNone(wc) self.assertEquals( wc.previous_certificate_id, wt.previous_certificate_id) self.assertAlmostEquals(wc.local_mean, wt.local_mean) self.assertAlmostEquals(wc.request_time, wt.request_time) self.assertAlmostEquals(wc.duration, wt.duration) self.assertEqual(wc.validator_address, wt.validator_address) self.assertEqual(wc.block_digest, "Reader's Digest") self.assertIsNotNone(wc.signature) self.assertIsNotNone(wc.identifier) # A newly-created wait certificate should be valid self.assertTrue(wc.is_valid([], signup_info.poet_public_key)) # Create another wait certificate and verify it is valid also wt = \ WaitTimer.create_wait_timer( validator_address='1660 Pennsylvania Avenue NW', certificates=[wc]) while not wt.has_expired(time.time()): time.sleep(1) # Now we can create a wait certificate and verify that it correlates # to the wait timer we just created another_wc = \ WaitCertificate.create_wait_certificate( wait_timer=None, block_digest="Pepto Bismol") self.assertTrue( another_wc.is_valid([wc], signup_info.poet_public_key))
def test_basic_create_signup_info(self): signup_info = \ SignupInfo.create_signup_info( validator_address='1660 Pennsylvania Avenue NW', originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id=NullIdentifier) self.assertIsNotNone(signup_info.poet_public_key) self.assertIsNotNone(signup_info.proof_data) self.assertIsNotNone(signup_info.anti_sybil_id) self.assertIsNotNone(signup_info.sealed_signup_data)
def test_create_wait_certificate(self): # Need to create signup information and wait timer first signup_info = \ SignupInfo.create_signup_info( validator_address='1660 Pennsylvania Avenue NW', originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id=NullIdentifier) wt = \ WaitTimer.create_wait_timer( validator_address='1660 Pennsylvania Avenue NW', certificates=[]) while not wt.has_expired(time.time()): time.sleep(1) # Now we can create a wait certificate and verify that it correlates # to the wait timer we just created wc = \ WaitCertificate.create_wait_certificate( wait_timer=wt, block_digest="Reader's Digest") self.assertIsNotNone(wc) self.assertEqual( wc.previous_certificate_id, wt.previous_certificate_id) self.assertAlmostEqual(wc.local_mean, wt.local_mean) self.assertAlmostEqual(wc.request_time, wt.request_time) self.assertAlmostEqual(wc.duration, wt.duration) self.assertEqual(wc.validator_address, wt.validator_address) self.assertEqual(wc.block_digest, "Reader's Digest") self.assertIsNotNone(wc.signature) self.assertIsNotNone(wc.identifier) # A newly-created wait certificate should be valid wc.check_valid([], signup_info.poet_public_key) # Create another wait certificate and verify it is valid also wt = \ WaitTimer.create_wait_timer( validator_address='1660 Pennsylvania Avenue NW', certificates=[wc]) while not wt.has_expired(time.time()): time.sleep(1) # Now we can create a wait certificate and verify that it correlates # to the wait timer we just created another_wc = \ WaitCertificate.create_wait_certificate( wait_timer=wt, block_digest="Pepto Bismol") another_wc.check_valid([wc], signup_info.poet_public_key)
def test_non_matching_originator_public_key(self): signup_info = \ SignupInfo.create_signup_info( validator_address='1660 Pennsylvania Avenue NW', originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id=NullIdentifier) with self.assertRaises(ValueError): signup_info.check_valid( originator_public_key_hash=self._another_public_key_hash, most_recent_wait_certificate_id=NullIdentifier)
def test_verify_signup_info(self): signup_info = \ SignupInfo.create_signup_info( originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id=NullIdentifier) try: signup_info.check_valid( originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id=NullIdentifier) except SignupInfoError as e: self.fail('Error with SignupInfo: {}'.format(e))
def test_create_wait_certificate_with_reused_wait_timer(self): # Need to create signup information SignupInfo.create_signup_info( validator_address='1660 Pennsylvania Avenue NW', originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id=NullIdentifier) # Create a wait certificate for the genesis block so that we can # create another wait certificate that has to play by the rules. wt = \ WaitTimer.create_wait_timer( validator_address='1660 Pennsylvania Avenue NW', certificates=[]) wc = \ WaitCertificate.create_wait_certificate( wait_timer=wt, block_digest="Reader's Digest") consumed_wt = wt # Verify that we cannot use the consumed wait timer to create a wait # certificate either before or after creating a new wait timer with self.assertRaises(ValueError): WaitCertificate.create_wait_certificate( wait_timer=consumed_wt, block_digest="Reader's Digest") wt = \ WaitTimer.create_wait_timer( validator_address='1660 Pennsylvania Avenue NW', certificates=[wc]) with self.assertRaises(ValueError): WaitCertificate.create_wait_certificate( wait_timer=consumed_wt, block_digest="Reader's Digest") # Verify that once the new timer expires, we can create a wait # certificate with it while not wt.has_expired(time.time()): time.sleep(1) WaitCertificate.create_wait_certificate(wait_timer=wt, block_digest="Reader's Digest")
def test_verify_signup_info(self): signup_info = \ SignupInfo.create_signup_info( validator_address='1660 Pennsylvania Avenue NW', originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id=NullIdentifier) try: signup_info.check_valid( originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id=NullIdentifier) except ValueError as e: self.fail('Error with SignupInfo: {}'.format(e))
def __init__(self, minfo=None): """Constructor for Update class. Args: minfo (dict): Update values extracted from a message {'verb', 'validator_name', 'validator_id', 'signup_info'} """ if minfo is None: minfo = {} self.verb = minfo.get('verb', 'reg') self.validator_name = minfo.get('validator_name', '') self.validator_id = minfo.get('validator_id', NullIdentifier) self.signup_info = \ SignupInfo.signup_info_from_serialized(minfo.get('signup_info'))
def test_non_matching_most_recent_wait_certificate_id(self): signup_info = \ SignupInfo.create_signup_info( originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id=NullIdentifier) # NOTE - this requires that the signup information check for validity # actually make this check. Currently the check is not done. # Once the check is added back, it should raise a # SignupInfoError exception and this test will fail, alerting # you that you need to wrap the call in self.assertRaises # # with self.assertRaises(SignupInfoError): signup_info.check_valid( originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id='SomeFunkyCertificateID')
def register_signup_information(self, journal): wait_certificate_id = journal.most_recent_committed_block_id public_key_hash = \ hashlib.sha256( signing.encode_pubkey(journal.local_node.public_key(), 'hex')).hexdigest() signup_info = \ SignupInfo.create_signup_info( validator_address=journal.local_node.signing_address(), originator_public_key_hash=public_key_hash, most_recent_wait_certificate_id=wait_certificate_id) # Save off the sealed signup data and cache the PoET public key journal.local_store.set( 'sealed_signup_data', signup_info.sealed_signup_data) journal.local_store.sync() self.poet_public_key = signup_info.poet_public_key LOGGER.debug( 'Register %s (%s)', journal.local_node.Name, journal.local_node.Identifier) # Create a validator register transaction and sign it. Wrap # the transaction in a message. Broadcast it to out. transaction = \ val_reg.ValidatorRegistryTransaction.register_validator( journal.local_node.Name, journal.local_node.Identifier, signup_info) transaction.sign_from_node(journal.local_node) message = \ val_reg.ValidatorRegistryTransactionMessage() message.Transaction = transaction LOGGER.info( 'Advertise PoET 1 validator %s (ID = %s) has PoET public key ' '%s', journal.local_node.Name, journal.local_node.Identifier, signup_info.poet_public_key) journal.gossip.broadcast_message(message)
def test_non_matching_most_recent_wait_certificate_id(self): signup_info = \ SignupInfo.create_signup_info( validator_address='1660 Pennsylvania Avenue NW', originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id=NullIdentifier) # NOTE - this requires that the signup information check for validity # actually make this check. Currently the check is not done. # Once the check is added back, it should raise a # ValueError exception and this test will fail, alerting # you that you need to wrap the call in self.assertRaises # # with self.assertRaises(ValueError): signup_info.check_valid( originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id='SomeFunkyCertificateID')
def _on_journal_initialization_complete(self, journal): """ Callback journal makes after the journal has completed initialization Args: journal (Journal): The journal object that has completed initialization. Returns: True """ # If we have sealed signup data (meaning that we have previously # created signup info), we can request that the enclave unseal it, # in the process restoring the enclave to its previous state. If # we don't have sealed signup data. If we don't have sealed signup # data, we need to create and register it. # # Note - this MUST be done AFTER the journal has completed # initialization so that there is at least one peer node to which # we can send the validator registry transaction to. Otherwise, # we will never, ever be able to be added to the validator registry # and, to paraphrase Martha Stewart, that is a bad thing. sealed_signup_data = journal.local_store.get('sealed_signup_data') if sealed_signup_data is not None: self.poet_public_key = \ SignupInfo.unseal_signup_data( validator_address=journal.local_node.signing_address(), sealed_signup_data=sealed_signup_data) LOGGER.info( 'Restore signup info for %s (ID = %s, PoET public key = %s)', journal.local_node.Name, journal.local_node.Identifier, self.poet_public_key) else: self.register_signup_information(journal) return True
def _on_journal_initialization_complete(self, journal): """ Callback journal makes after the journal has completed initialization Args: journal (Journal): The journal object that has completed initialization. Returns: True """ # If we have sealed signup data (meaning that we have previously # created signup info), we can request that the enclave unseal it, # in the process restoring the enclave to its previous state. If # we don't have sealed signup data, we need to create and register it. # # Note - this MUST be done AFTER the journal has completed # initialization so that there is at least one peer node to which # we can send the validator registry transaction to. Otherwise, # we will never, ever be able to be added to the validator registry # and, to paraphrase Martha Stewart, that is a bad thing. sealed_signup_data = journal.local_store.get('sealed_signup_data') if sealed_signup_data is not None: self.poet_public_key = \ SignupInfo.unseal_signup_data( validator_address=journal.local_node.signing_address(), sealed_signup_data=sealed_signup_data) LOGGER.info( 'Restore signup info for %s (ID = %s, PoET public key = %s)', journal.local_node.Name, journal.local_node.Identifier, self.poet_public_key) else: self.register_signup_information(journal) return True
def test_create_wait_timer(self): # Need to create signup information first signup_info = \ SignupInfo.create_signup_info( validator_address='1060 W Addison Street', originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id=NullIdentifier) stake_in_the_sand = time.time() # An empty certificate list should result in a local mean that is # the target wait time wt = wait_timer.WaitTimer.create_wait_timer( validator_address='1060 W Addison Street', certificates=[]) self.assertIsNotNone(wt) self.assertEqual(wt.local_mean, wait_timer.WaitTimer.target_wait_time) self.assertEqual(wt.previous_certificate_id, NullIdentifier) self.assertGreaterEqual(wt.request_time, stake_in_the_sand) self.assertLessEqual(wt.request_time, time.time()) self.assertGreaterEqual(wt.duration, wait_timer.WaitTimer.minimum_wait_time) self.assertEqual(wt.validator_address, '1060 W Addison Street') wt = wait_timer.WaitTimer.create_wait_timer( validator_address='1060 W Addison Street', certificates=tuple()) self.assertIsNotNone(wt) self.assertEqual(wt.local_mean, wait_timer.WaitTimer.target_wait_time) self.assertEqual(wt.previous_certificate_id, NullIdentifier) self.assertGreaterEqual(wt.request_time, stake_in_the_sand) self.assertLessEqual(wt.request_time, time.time()) self.assertGreaterEqual(wt.duration, wait_timer.WaitTimer.minimum_wait_time) self.assertEqual(wt.validator_address, '1060 W Addison Street') # Ensure that the enclave is set back to initial state SignupInfo.poet_enclave = reload(poet_enclave) wait_timer.WaitTimer.poet_enclave = SignupInfo.poet_enclave # Make sure that trying to create a wait timer before signup # information is provided causes an error with self.assertRaises(ValueError): wait_timer.WaitTimer.create_wait_timer( validator_address='1060 W Addison Street', certificates=[]) with self.assertRaises(ValueError): wait_timer.WaitTimer.create_wait_timer( validator_address='1060 W Addison Street', certificates=tuple()) # Initialize the enclave with sealed signup data SignupInfo.unseal_signup_data( validator_address='1660 Pennsylvania Avenue NW', sealed_signup_data=signup_info.sealed_signup_data) stake_in_the_sand = time.time() # An empty certificate list should result in a local mean that is # the target wait time wt = wait_timer.WaitTimer.create_wait_timer( validator_address='1060 W Addison Street', certificates=[]) self.assertIsNotNone(wt) self.assertEqual(wt.local_mean, wait_timer.WaitTimer.target_wait_time) self.assertEqual(wt.previous_certificate_id, NullIdentifier) self.assertGreaterEqual(wt.request_time, stake_in_the_sand) self.assertLessEqual(wt.request_time, time.time()) self.assertGreaterEqual(wt.duration, wait_timer.WaitTimer.minimum_wait_time) self.assertEqual(wt.validator_address, '1060 W Addison Street') wt = wait_timer.WaitTimer.create_wait_timer( validator_address='1600 Pennsylvania Avenue NW', certificates=tuple()) self.assertIsNotNone(wt) self.assertEqual(wt.local_mean, wait_timer.WaitTimer.target_wait_time) self.assertEqual(wt.previous_certificate_id, NullIdentifier) self.assertGreaterEqual(wt.request_time, stake_in_the_sand) self.assertLessEqual(wt.request_time, time.time()) self.assertGreaterEqual(wt.duration, wait_timer.WaitTimer.minimum_wait_time) self.assertEqual(wt.validator_address, '1600 Pennsylvania Avenue NW')
def test_create_wait_timer(self): # Need to create signup information first signup_info = \ SignupInfo.create_signup_info( validator_address='1060 W Addison Street', originator_public_key_hash=self._originator_public_key_hash, most_recent_wait_certificate_id=NullIdentifier) stake_in_the_sand = time.time() # An empty certificate list should result in a local mean that is # the target wait time wt = wait_timer.WaitTimer.create_wait_timer( validator_address='1060 W Addison Street', certificates=[]) self.assertIsNotNone(wt) self.assertEqual(wt.local_mean, wait_timer.WaitTimer.target_wait_time) self.assertEqual(wt.previous_certificate_id, NullIdentifier) self.assertGreaterEqual(wt.request_time, stake_in_the_sand) self.assertLessEqual(wt.request_time, time.time()) self.assertGreaterEqual( wt.duration, wait_timer.WaitTimer.minimum_wait_time) self.assertEqual(wt.validator_address, '1060 W Addison Street') wt = wait_timer.WaitTimer.create_wait_timer( validator_address='1060 W Addison Street', certificates=tuple()) self.assertIsNotNone(wt) self.assertEqual(wt.local_mean, wait_timer.WaitTimer.target_wait_time) self.assertEqual(wt.previous_certificate_id, NullIdentifier) self.assertGreaterEqual(wt.request_time, stake_in_the_sand) self.assertLessEqual(wt.request_time, time.time()) self.assertGreaterEqual( wt.duration, wait_timer.WaitTimer.minimum_wait_time) self.assertEqual(wt.validator_address, '1060 W Addison Street') # Ensure that the enclave is set back to initial state SignupInfo.poet_enclave = reload(poet_enclave) wait_timer.WaitTimer.poet_enclave = SignupInfo.poet_enclave # Make sure that trying to create a wait timer before signup # information is provided causes an error with self.assertRaises(ValueError): wait_timer.WaitTimer.create_wait_timer( validator_address='1060 W Addison Street', certificates=[]) with self.assertRaises(ValueError): wait_timer.WaitTimer.create_wait_timer( validator_address='1060 W Addison Street', certificates=tuple()) # Initialize the enclave with sealed signup data SignupInfo.unseal_signup_data( validator_address='1660 Pennsylvania Avenue NW', sealed_signup_data=signup_info.sealed_signup_data) stake_in_the_sand = time.time() # An empty certificate list should result in a local mean that is # the target wait time wt = wait_timer.WaitTimer.create_wait_timer( validator_address='1060 W Addison Street', certificates=[]) self.assertIsNotNone(wt) self.assertEqual(wt.local_mean, wait_timer.WaitTimer.target_wait_time) self.assertEqual(wt.previous_certificate_id, NullIdentifier) self.assertGreaterEqual(wt.request_time, stake_in_the_sand) self.assertLessEqual(wt.request_time, time.time()) self.assertGreaterEqual( wt.duration, wait_timer.WaitTimer.minimum_wait_time) self.assertEqual(wt.validator_address, '1060 W Addison Street') wt = wait_timer.WaitTimer.create_wait_timer( validator_address='1600 Pennsylvania Avenue NW', certificates=tuple()) self.assertIsNotNone(wt) self.assertEqual(wt.local_mean, wait_timer.WaitTimer.target_wait_time) self.assertEqual(wt.previous_certificate_id, NullIdentifier) self.assertGreaterEqual(wt.request_time, stake_in_the_sand) self.assertLessEqual(wt.request_time, time.time()) self.assertGreaterEqual( wt.duration, wait_timer.WaitTimer.minimum_wait_time) self.assertEqual(wt.validator_address, '1600 Pennsylvania Avenue NW')
def initialization_complete(self, journal): """Processes all invocations that arrived while the ledger was being initialized. """ # Before we allow the base journal to do anything that might result # in a wait timer or wait certificate being created, we have to ensure # the PoET enclave has been initialized. This can be done in one of # two ways: # 1. If we have sealed signup data (meaning that we have previously # created signup info), we can request that the enclave unseal it, # in the process restoring the enclave to its previous state. # 2. Create new signup information. signup_info = None sealed_signup_data = journal.local_store.get('sealed_signup_data') if sealed_signup_data is not None: self.poet_public_key = SignupInfo.unseal_signup_data( sealed_signup_data=sealed_signup_data) else: wait_certificate_id = journal.most_recent_committed_block_id public_key_hash = \ hashlib.sha256( pybitcointools.encode_pubkey( journal.local_node.public_key(), 'hex')).hexdigest() signup_info = \ SignupInfo.create_signup_info( originator_public_key_hash=public_key_hash, most_recent_wait_certificate_id=wait_certificate_id) # Save off the sealed signup data journal.local_store.set('sealed_signup_data', signup_info.sealed_signup_data) journal.local_store.sync() self.poet_public_key = signup_info.poet_public_key # propagate the maximum blocks to keep journal.maximum_blocks_to_keep = max( journal.maximum_blocks_to_keep, WaitTimer.certificate_sample_length) # initialize stats specifically for the block chain journal journal.JournalStats.add_metric(stats.Value('LocalMeanTime', 0)) journal.JournalStats.add_metric(stats.Value('AggregateLocalMean', 0)) journal.JournalStats.add_metric(stats.Value('PopulationEstimate', 0)) journal.JournalStats.add_metric( stats.Value('ExpectedExpirationTime', 0)) journal.JournalStats.add_metric(stats.Value('Duration', 0)) # initialize the block handlers poet_transaction_block.register_message_handlers(journal) # If we created signup information, then advertise self to network if signup_info is not None: # Create a validator register transaction and sign it. Wrap # the transaction in a message. Broadcast it to out. transaction = \ val_reg.ValidatorRegistryTransaction.register_validator( journal.local_node.Name, journal.local_node.Identifier, signup_info) transaction.sign_from_node(journal.local_node) message = \ val_reg.ValidatorRegistryTransactionMessage() message.Transaction = transaction LOGGER.info('Advertise PoET 1 validator with name %s', journal.local_node.Name) journal.gossip.broadcast_message(message)