def test_actioninitchain_restore(): """ ActionInitChain *must* restore the previous pseudo random generator state. Message identifiers are used for confirmation messages, e.g. delivered and processed messages, therefore it's important for each message identifier to not collide with a previous identifier, for this reason the PRNG is used. Additionally, during restarts the state changes are reapplied, and it's really important for the re-execution of the state changes to be deterministic, otherwise undefined behavior may happen. For this reason the state of the PRNG must be restored. If the above is not respected, the message ids generated during restart will not match the previous IDs and the message queues won't be properly cleared up. """ pseudo_random_generator = random.Random() block_number = 577 our_address = factories.make_address() chain_id = 777 original_obj = state_change.ActionInitChain( pseudo_random_generator=pseudo_random_generator, block_number=block_number, block_hash=factories.make_block_hash(), our_address=our_address, chain_id=chain_id, ) decoded_obj = JSONSerializer.deserialize( JSONSerializer.serialize(original_obj)) assert original_obj == decoded_obj
def test_serialize_contract_send_subclass(chain_state): """Serializing must preserve class Regression test for https://github.com/raiden-network/raiden/issues/6075 """ canonical_identifier = CanonicalIdentifier( chain_identifier=ChainID(1), token_network_address=TokenNetworkAddress(factories.make_address()), channel_identifier=factories.make_channel_identifier(), ) chain_state.pending_transactions = [ ContractSendChannelClose( canonical_identifier=canonical_identifier, triggered_by_block_hash=factories.make_block_hash(), balance_proof=None, ) ] serialized_chain_state = JSONSerializer.serialize(chain_state) deserialized_chain_state = JSONSerializer.deserialize( serialized_chain_state) assert ( chain_state.pending_transactions[0].__class__.__name__ == deserialized_chain_state.pending_transactions[0].__class__.__name__) assert chain_state == deserialized_chain_state
def test_restore_queueids_to_queues(chain_state, netting_channel_state): """Test that withdraw messages are restorable if they exist in chain_state.queueids_to_queues. """ recipient = netting_channel_state.partner_state.address queue_identifier = QueueIdentifier( recipient=recipient, canonical_identifier=netting_channel_state.canonical_identifier) msg_args = dict( recipient=recipient, canonical_identifier=netting_channel_state.canonical_identifier, message_identifier=factories.make_message_identifier(), total_withdraw=WithdrawAmount(1), participant=recipient, expiration=BlockExpiration(10), nonce=Nonce(15), ) messages = [ SendWithdrawRequest(**msg_args), SendWithdrawConfirmation(**msg_args), SendWithdrawExpired(**msg_args), ] chain_state.queueids_to_queues[queue_identifier] = messages serialized_chain_state = JSONSerializer.serialize(chain_state) deserialized_chain_state = JSONSerializer.deserialize( serialized_chain_state) assert chain_state == deserialized_chain_state
def test_mediated_transfer_min_max(amount, payment_identifier, nonce, transferred_amount): mediated_transfer = factories.create( factories.LockedTransferProperties( amount=amount, payment_identifier=payment_identifier, nonce=nonce, transferred_amount=transferred_amount, ) ) mediated_transfer.sign(signer) data = JSONSerializer.serialize(mediated_transfer) assert JSONSerializer.deserialize(data) == mediated_transfer
def test_send_refund_transfer_contains_balance_proof(): recipient = factories.make_address() transfer = factories.create(factories.LockedTransferUnsignedStateProperties()) message_identifier = 1 event = SendRefundTransfer( recipient=recipient, message_identifier=message_identifier, transfer=transfer, canonical_identifier=factories.make_canonical_identifier(), ) assert hasattr(event, "balance_proof") assert JSONSerializer.deserialize(JSONSerializer.serialize(event)) == event
def test_refund_transfer_min_max(amount, payment_identifier, nonce, transferred_amount): refund_transfer = factories.create( factories.RefundTransferProperties( amount=amount, payment_identifier=payment_identifier, nonce=nonce, transferred_amount=transferred_amount, ) ) refund_transfer.sign(signer) data = JSONSerializer.serialize(refund_transfer) assert JSONSerializer.deserialize(data) == refund_transfer
def test_serialization_networkx_graph(): p1 = to_canonical_address("0x5522070585a1a275631ba69c444ac0451AA9Fe4C") p2 = to_canonical_address("0x5522070585a1a275631ba69c444ac0451AA9Fe4D") p3 = to_canonical_address("0x5522070585a1a275631ba69c444ac0451AA9Fe4E") p4 = to_canonical_address("0x5522070585a1a275631ba69c444ac0451AA9Fe4F") e = [(p1, p2), (p2, p3), (p3, p4)] graph = Graph(e) instance = ClassWithGraphObject(graph) data = JSONSerializer.serialize(instance) restored_instance = JSONSerializer.deserialize(data) assert instance.graph.edges == restored_instance.graph.edges
def test_chainstate_restore(): pseudo_random_generator = random.Random() block_number = 577 our_address = factories.make_address() chain_id = 777 original_obj = state.ChainState( pseudo_random_generator=pseudo_random_generator, block_number=block_number, block_hash=factories.make_block_hash(), our_address=our_address, chain_id=chain_id, ) decoded_obj = JSONSerializer.deserialize(JSONSerializer.serialize(original_obj)) assert original_obj == decoded_obj
def test_upgrade_manager_restores_backup(tmp_path, monkeypatch): db_path = tmp_path / Path("v17_log.db") old_db_filename = tmp_path / Path("v16_log.db") with patch("raiden.storage.sqlite.RAIDEN_DB_VERSION", new=16), SQLiteStorage(str(old_db_filename)) as storage: state_change = ActionInitChain( chain_id=1, our_address=factories.make_address(), block_number=1, block_hash=factories.make_block_hash(), pseudo_random_generator=random.Random(), ) action_init_chain_data = JSONSerializer.serialize(state_change) storage.write_state_changes(state_changes=[action_init_chain_data]) storage.update_version() upgrade_functions = [UpgradeRecord(from_version=16, function=Mock())] upgrade_functions[0].function.return_value = 17 web3, _ = create_fake_web3_for_block_hash(number_of_blocks=1) with monkeypatch.context() as m: m.setattr(raiden.utils.upgrades, "UPGRADES_LIST", upgrade_functions) m.setattr(raiden.utils.upgrades, "RAIDEN_DB_VERSION", 19) UpgradeManager(db_filename=db_path, web3=web3).run() # Once restored, the state changes written above should be # in the restored database with SQLiteStorage(str(db_path)) as storage: state_change_record = storage.get_latest_state_change_by_data_field( FilteredDBQuery( filters=[{ "_type": "raiden.transfer.state_change.ActionInitChain" }], main_operator=Operator.NONE, inner_operator=Operator.NONE, )) assert state_change_record.data is not None
def test_serialize_missing_attribute(): instance = ClassWithInt(1) instance.value = b"a" with pytest.raises(SerializationError): JSONSerializer.serialize(instance)
def test_serialize_wrong_type(): with pytest.raises(SerializationError): JSONSerializer.serialize([])