├── .bumpversion_client.cfg ├── .circleci ├── conditional_skip.sh ├── config.yml ├── fetch_geth_parity_solc.sh ├── fetch_geth_solc.sh ├── fetch_pr_base_commit.sh ├── fetch_ssh_hostkey.sh ├── get_archive_tag.sh └── upload_to_s3.sh ├── .codecov.yml ├── .dockerignore ├── .editorconfig ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── critical_vulnerability_report.md │ └── feature_request.md └── PULL_REQUEST_TEMPLATE │ ├── bugfix.md │ ├── feature.md │ └── refactoring.md ├── .gitignore ├── .pylint.rc ├── .travis.yml ├── Article.md ├── CONTRIBUTING.md ├── LICENSE ├── Lumino.png ├── MANIFEST.in ├── Makefile ├── None.lock ├── README.md ├── README.rst ├── config.json ├── config_sample.toml ├── constraints-dev.txt ├── constraints.txt ├── definitions.py ├── docker ├── Dockerfile ├── build.Dockerfile ├── raiden.desktop └── raiden.svg ├── docs ├── .DS_Store ├── 0.0.1 │ ├── .DS_Store │ ├── Lumino.png │ ├── README.md │ ├── install_macos.md │ └── install_ubuntu.md ├── 0.0.2 │ ├── .DS_Store │ ├── Lumino.png │ ├── README.md │ ├── install_macos.md │ └── install_ubuntu.md ├── 0.0.4 │ ├── Lumino.png │ ├── README.md │ ├── install_macos.md │ └── install_ubuntu.md ├── Makefile ├── Thoughts-on-Performance.md ├── Token-Swap.md ├── _static │ ├── sphinxcontrib-httpexample.css │ └── sphinxcontrib-httpexample.js ├── api_walkthrough.rst ├── changelog.rst ├── conf.py ├── config_file.rst ├── glossary.rst ├── images │ ├── architecture_overview.png │ ├── channelsgraph.png │ ├── merkletree.png │ ├── pending_transfers_for_mediator.gif │ ├── raiden_webui_channels_page_screenshot.png │ ├── raiden_webui_landing_page_screenshot.png │ ├── raiden_webui_tokens_page_screenshot.png │ ├── restore_wal.png │ ├── routing_a_transfer.gif │ ├── settle_pending_locks.gif │ ├── state_tasks.png │ ├── transfer_happy_case.gif │ ├── transfer_unhappy_case.gif │ └── write_state_change_to_wal.png ├── index.rst ├── macos_install_guide.rst ├── nix.rst ├── onboarding.rst ├── overview_and_guide.rst ├── raiden.png ├── red_eyes_mainnet_tutorial.rst ├── rest_api.rst ├── state_machines.rst ├── trademarks.rst └── webui_tutorial.rst ├── nix ├── envrc-nix-python ├── leveldb.nix └── shell.nix ├── pip-wheel-metadata └── raiden.dist-info │ ├── LICENSE │ ├── METADATA │ ├── entry_points.txt │ └── top_level.txt ├── pylintrc ├── pyproject.toml ├── raiden.spec ├── raiden ├── None ├── None.lock ├── __main__.py ├── accounts.py ├── api │ ├── __init__.py │ ├── objects.py │ ├── python.py │ ├── rest.py │ ├── v1 │ │ ├── __init__.py │ │ ├── encoding.py │ │ └── resources.py │ ├── validations │ │ ├── __init__.py │ │ ├── api_error_builder.py │ │ ├── api_status_codes.py │ │ ├── channel_validator.py │ │ └── validation_result.py │ └── webui │ │ ├── index.html │ │ └── static │ │ ├── css │ │ ├── 2.8ac89622.chunk.css │ │ ├── 2.8ac89622.chunk.css.map │ │ ├── 2.9bbc34cb.chunk.css │ │ ├── 2.9bbc34cb.chunk.css.map │ │ ├── main.33e62088.chunk.css │ │ ├── main.33e62088.chunk.css.map │ │ ├── main.b9f7d34e.chunk.css │ │ └── main.b9f7d34e.chunk.css.map │ │ ├── endpointConfig.js │ │ ├── icon.ico │ │ ├── js │ │ ├── 2.16f1130d.chunk.js │ │ ├── 2.16f1130d.chunk.js.map │ │ ├── 2.1fc57828.chunk.js │ │ ├── 2.1fc57828.chunk.js.map │ │ ├── main.5ae40adb.chunk.js │ │ ├── main.5ae40adb.chunk.js.map │ │ ├── main.f7476159.chunk.js │ │ ├── main.f7476159.chunk.js.map │ │ ├── runtime~main.a8a9905a.js │ │ └── runtime~main.a8a9905a.js.map │ │ ├── manifest.json │ │ └── media │ │ ├── fa-brands-400.475a2674.eot │ │ ├── fa-brands-400.4acb4cc4.woff │ │ ├── fa-brands-400.82110f5d.svg │ │ ├── fa-brands-400.99f3121d.woff2 │ │ ├── fa-brands-400.b00fd7db.ttf │ │ ├── fa-light-300.1e4c8262.woff │ │ ├── fa-light-300.64805970.eot │ │ ├── fa-light-300.67557ec3.woff2 │ │ ├── fa-light-300.69ecb2bd.ttf │ │ ├── fa-light-300.b6e4c702.svg │ │ ├── fa-regular-400.1c840fa5.svg │ │ ├── fa-regular-400.b8561728.woff │ │ ├── fa-regular-400.dd9e1583.eot │ │ ├── fa-regular-400.ea1125e0.woff2 │ │ ├── fa-regular-400.f18935cd.ttf │ │ ├── fa-solid-900.00d30127.woff2 │ │ ├── fa-solid-900.3f7e3ac8.eot │ │ ├── fa-solid-900.9242dedf.ttf │ │ ├── fa-solid-900.ad34988a.svg │ │ ├── fa-solid-900.dddc7b46.woff │ │ ├── logo-rif.8da9e5f3.svg │ │ └── lumino-v.595d2e99.svg ├── app.py ├── billing │ ├── __init__.py │ └── invoices │ │ ├── __init__.py │ │ ├── constants │ │ ├── errors.py │ │ ├── invoice_status.py │ │ └── invoice_type.py │ │ ├── decoder │ │ ├── __init__.py │ │ └── invoice_decoder.py │ │ ├── encoder │ │ ├── __init__.py │ │ └── invoice_encoder.py │ │ ├── handlers │ │ └── invoice_handler.py │ │ ├── invoice.py │ │ ├── options_args.py │ │ └── util │ │ ├── __init__.py │ │ ├── bech32.py │ │ ├── encoding_util.py │ │ ├── encryption_util.py │ │ ├── random_util.py │ │ └── time_util.py ├── blockchain │ ├── __init__.py │ ├── events.py │ └── state.py ├── blockchain_events_handler.py ├── connection_manager.py ├── constants.py ├── encoding │ ├── __init__.py │ ├── encoders.py │ ├── format.py │ └── messages.py ├── exceptions.py ├── lightclient │ ├── __init__.py │ ├── client_model.py │ ├── light_client_message_handler.py │ ├── light_client_service.py │ ├── light_client_utils.py │ └── lightclientmessages │ │ ├── __init__.py │ │ ├── hub_message.py │ │ ├── light_client_non_closing_balance_proof.py │ │ ├── light_client_payment.py │ │ └── light_client_protocol_message.py ├── log_config.py ├── message_event_convertor.py ├── message_handler.py ├── messages.py ├── network │ ├── __init__.py │ ├── blockchain_service.py │ ├── discovery.py │ ├── pathfinding.py │ ├── proxies │ │ ├── README.md │ │ ├── __init__.py │ │ ├── discovery.py │ │ ├── payment_channel.py │ │ ├── secret_registry.py │ │ ├── service_registry.py │ │ ├── token.py │ │ ├── token_network.py │ │ ├── token_network_registry.py │ │ ├── user_deposit.py │ │ └── utils.py │ ├── resolver │ │ ├── __init__.py │ │ └── client.py │ ├── rpc │ │ ├── __init__.py │ │ ├── client.py │ │ ├── middleware.py │ │ ├── smartcontract_proxy.py │ │ └── transactions.py │ ├── sockfactory.py │ ├── stunsock.py │ ├── throttle.py │ ├── transport │ │ ├── __init__.py │ │ ├── matrix │ │ │ ├── __init__.py │ │ │ ├── client.py │ │ │ ├── transport.py │ │ │ └── utils.py │ │ └── udp │ │ │ ├── __init__.py │ │ │ ├── healthcheck.py │ │ │ ├── udp_transport.py │ │ │ └── udp_utils.py │ ├── upnpsock.py │ └── utils.py ├── py.typed ├── raiden_event_handler.py ├── raiden_service.py ├── rns_constants.py ├── routing.py ├── schedulers │ ├── __init__.py │ ├── alive_schedule.py │ └── setup.py ├── settings.py ├── smoketest_genesis.json ├── storage │ ├── __init__.py │ ├── migrations │ │ ├── __init__.py │ │ ├── v16_to_v17.py │ │ ├── v17_to_v18.py │ │ ├── v18_to_v19.py │ │ ├── v19_to_v20.py │ │ ├── v20_to_v21.py │ │ └── v21_to_v22.py │ ├── restore.py │ ├── serialize.py │ ├── sqlite.py │ ├── utils.py │ ├── versions.py │ └── wal.py ├── tasks.py ├── test.txt ├── tests │ ├── README.rst │ ├── __init__.py │ ├── benchmark │ │ ├── __init__.py │ │ └── utils.py │ ├── conftest.py │ ├── fixtures │ │ ├── __init__.py │ │ ├── constants.py │ │ └── variables.py │ ├── fuzz │ │ ├── conftest.py │ │ └── test_state_changes.py │ ├── integration │ │ ├── __init__.py │ │ ├── api │ │ │ ├── __init__.py │ │ │ ├── conftest.py │ │ │ ├── fixtures.py │ │ │ ├── test_pythonapi.py │ │ │ ├── test_pythonapi_regression.py │ │ │ ├── test_restapi.py │ │ │ └── utils.py │ │ ├── cli │ │ │ ├── conftest.py │ │ │ ├── test_cli_development.py │ │ │ ├── test_cli_production.py │ │ │ └── util.py │ │ ├── conftest.py │ │ ├── fixtures │ │ │ ├── __init__.py │ │ │ ├── blockchain.py │ │ │ ├── raiden_network.py │ │ │ ├── smartcontracts.py │ │ │ └── transport.py │ │ ├── long_running │ │ │ ├── __init__.py │ │ │ ├── test_integration_events.py │ │ │ ├── test_settlement.py │ │ │ ├── test_stress.py │ │ │ └── test_token_networks.py │ │ ├── network │ │ │ ├── __init__.py │ │ │ ├── proxies │ │ │ │ ├── __init__.py │ │ │ │ ├── test_discovery.py │ │ │ │ ├── test_payment_channel.py │ │ │ │ ├── test_secret_registry.py │ │ │ │ ├── test_service_registry.py │ │ │ │ ├── test_token.py │ │ │ │ ├── test_token_network.py │ │ │ │ └── test_token_network_registry.py │ │ │ └── transport │ │ │ │ ├── __init__.py │ │ │ │ ├── test_matrix_transport.py │ │ │ │ └── test_udp.py │ │ ├── rpc │ │ │ ├── __init__.py │ │ │ ├── assumptions │ │ │ │ ├── test_parity_rpc_assumptions.py │ │ │ │ ├── test_rpc_call_assumptions.py │ │ │ │ ├── test_rpc_filters_assumptions.py │ │ │ │ ├── test_rpc_gas_estimation_assumptions.py │ │ │ │ ├── test_rpc_gas_price_assumptions.py │ │ │ │ └── test_rpc_transaction_assumptions.py │ │ │ └── test_client.py │ │ ├── test_balance_proof_check.py │ │ ├── test_blockchainservice.py │ │ ├── test_echo_node.py │ │ ├── test_pythonapi.py │ │ ├── test_raidenservice.py │ │ ├── test_recovery.py │ │ ├── test_regression.py │ │ ├── test_regression_parity.py │ │ ├── test_send_queued_messages.py │ │ └── transfer │ │ │ ├── __init__.py │ │ │ ├── test_mediatedtransfer.py │ │ │ ├── test_mediatedtransfer_events.py │ │ │ ├── test_mediatedtransfer_invalid.py │ │ │ ├── test_refund_invalid.py │ │ │ └── test_refundtransfer.py │ ├── scenarios │ │ ├── ci │ │ │ ├── Scenario-Stress-Hub.yaml │ │ │ └── long_path_mediated_transfers.yaml │ │ ├── ms1_simple_monitoring.yaml │ │ ├── ms2_simple_monitoring.yaml │ │ ├── ms3_simple_monitoring.yaml │ │ ├── old_scenarios │ │ │ ├── Scenario-Kill-Receiver.yaml │ │ │ ├── Scenario-Mediated-Transfer-in-Hexagon.yaml │ │ │ ├── Scenario-Re-Routing.yaml │ │ │ ├── close_channel_all_channels.yaml │ │ │ ├── close_channel_one_channel.yaml │ │ │ ├── close_channel_reopen_before_settle.yaml │ │ │ ├── direct_transfers_happy_cases_1-1000_txs.yaml │ │ │ ├── direct_transfers_mixed_edge_cases.yaml │ │ │ ├── direct_transfers_stopped_node_scenarios.yaml │ │ │ ├── funding-channel-scenarios.yaml │ │ │ ├── join-network-scenario-J1.yaml │ │ │ ├── join-network-scenario-J10.yaml │ │ │ ├── join-network-scenario-J11.yaml │ │ │ ├── join-network-scenario-J12.yaml │ │ │ ├── join-network-scenario-J13.yaml │ │ │ ├── join-network-scenario-J15.yaml │ │ │ ├── join-network-scenario-J16.yaml │ │ │ ├── join-network-scenario-J17.yaml │ │ │ ├── join-network-scenario-J18.yaml │ │ │ ├── join-network-scenario-J19.yaml │ │ │ ├── join-network-scenario-J2.yaml │ │ │ ├── join-network-scenario-J3.yaml │ │ │ ├── join-network-scenario-J4.yaml │ │ │ ├── join-network-scenario-J6.yaml │ │ │ ├── join-network-scenario-J7.yaml │ │ │ ├── join-network-scenario-J8.yaml │ │ │ ├── join-network-scenario-J9.yaml │ │ │ ├── leave-network-happy-scenario.yaml │ │ │ ├── leave-network-on-closed_channels.yaml │ │ │ ├── leave-network-with-stopped-node.yaml │ │ │ ├── mediated-transfers-scnenarios.yaml │ │ │ └── open-channel-different-scenarios.yaml │ │ ├── pfs1_get_a_simple_path.yaml │ │ ├── pfs2_simple_no_path.yaml │ │ ├── pfs3_multiple_paths.yaml │ │ ├── pfs4_use_best_path.yaml │ │ ├── pfs5_too_low_capacity.yaml │ │ ├── pfs6_low_capacity.yaml │ │ └── pfs7_simple_path_rewards.yaml │ ├── smart_contracts │ │ ├── RpcTest.sol │ │ └── RpcWithStorageTest.sol │ ├── test_files │ │ ├── .gitignore │ │ ├── UTC--2016-10-26T16-55-53.551024336Z--0d5a0e4fece4b84365b9b8dba6e6d41348c73645 │ │ ├── UTC--2017-06-20T16-06-00.000000000Z--invalid │ │ ├── passwordfile.txt │ │ └── valid_keystorefile_with_unexpected_name │ ├── test_message_delivered.py │ ├── unit │ │ ├── __init__.py │ │ ├── api │ │ │ ├── __init__.py │ │ │ ├── test_api.py │ │ │ └── test_api_events.py │ │ ├── conftest.py │ │ ├── fixtures.py │ │ ├── lightclient_inputs.py │ │ ├── storage │ │ │ ├── __init__.py │ │ │ ├── migrations │ │ │ │ ├── data │ │ │ │ │ ├── v16_chainstate.json │ │ │ │ │ ├── v17_chainstate.json │ │ │ │ │ ├── v18_chainstate.json │ │ │ │ │ ├── v18_events.json │ │ │ │ │ ├── v18_statechanges.json │ │ │ │ │ ├── v19_chainstate.json │ │ │ │ │ ├── v19_statechanges.json │ │ │ │ │ ├── v20_chainstate.json │ │ │ │ │ ├── v20_statechanges.json │ │ │ │ │ ├── v21_chainstate.json │ │ │ │ │ ├── v21_events.json │ │ │ │ │ └── v21_statechanges.json │ │ │ │ ├── test_v16_to_v17.py │ │ │ │ ├── test_v17_to_v18.py │ │ │ │ ├── test_v18_to_v19.py │ │ │ │ ├── test_v19_to_v20.py │ │ │ │ ├── test_v20_to_v21.py │ │ │ │ └── test_v21_to_v22.py │ │ │ ├── test_storage.py │ │ │ └── test_versions.py │ │ ├── test_accounts.py │ │ ├── test_binary_encoding.py │ │ ├── test_channelstate.py │ │ ├── test_cli.py │ │ ├── test_dict_encoding.py │ │ ├── test_light_client_messages.py │ │ ├── test_lightclient_onboarding.py │ │ ├── test_logging.py │ │ ├── test_matrix_presence.py │ │ ├── test_matrix_transport.py │ │ ├── test_message_locked_transfer.py │ │ ├── test_messages.py │ │ ├── test_mock.py │ │ ├── test_mtree.py │ │ ├── test_namedbuffer.py │ │ ├── test_node_queue.py │ │ ├── test_notifyingqueue.py │ │ ├── test_operators.py │ │ ├── test_pfs_integration.py │ │ ├── test_raiden_event_handler.py │ │ ├── test_rpc.py │ │ ├── test_serialization.py │ │ ├── test_signature_lc.py │ │ ├── test_sqlite.py │ │ ├── test_startup.py │ │ ├── test_state.py │ │ ├── test_tokennetwork.py │ │ ├── test_udp_transport.py │ │ ├── test_upgrade.py │ │ ├── test_utils.py │ │ ├── test_version_check.py │ │ ├── test_wal.py │ │ ├── transfer │ │ │ ├── __init__.py │ │ │ ├── mediated_transfer │ │ │ │ ├── __init__.py │ │ │ │ ├── test_events.py │ │ │ │ ├── test_initiatorstate.py │ │ │ │ ├── test_mediatorstate.py │ │ │ │ ├── test_mediatorstate_regression.py │ │ │ │ └── test_targetstate.py │ │ │ ├── test_channel.py │ │ │ ├── test_node.py │ │ │ ├── test_state_diff.py │ │ │ └── test_utils.py │ │ └── utils │ │ │ ├── __init__.py │ │ │ ├── lighclient │ │ │ ├── __init__.py │ │ │ └── onboarding │ │ │ │ ├── __init__.py │ │ │ │ └── lightclient_inputs.py │ │ │ └── upgrades.py │ └── utils │ │ ├── __init__.py │ │ ├── app.py │ │ ├── client.py │ │ ├── detect_failure.py │ │ ├── eth_node.py │ │ ├── events.py │ │ ├── factories.py │ │ ├── genesis.py │ │ ├── migrations.py │ │ ├── mocks.py │ │ ├── network.py │ │ ├── protocol.py │ │ ├── smartcontracts.py │ │ ├── smoketest.py │ │ ├── synapse_config.yaml.template │ │ ├── tests.py │ │ ├── transfer.py │ │ └── transport.py ├── transfer │ ├── __init__.py │ ├── architecture.py │ ├── balance_proof.py │ ├── channel.py │ ├── events.py │ ├── identifiers.py │ ├── mediated_transfer │ │ ├── __init__.py │ │ ├── events.py │ │ ├── initiator.py │ │ ├── initiator_manager.py │ │ ├── mediator.py │ │ ├── state.py │ │ ├── state_change.py │ │ └── target.py │ ├── merkle_tree.py │ ├── node.py │ ├── queue_identifier.py │ ├── secret_registry.py │ ├── state.py │ ├── state_change.py │ ├── token_network.py │ ├── utils.py │ └── views.py ├── ui │ ├── __init__.py │ ├── app.py │ ├── checks.py │ ├── cli.py │ ├── config.py │ ├── console.py │ ├── explorer.py │ ├── prompt.py │ ├── runners.py │ ├── startup.py │ └── sync.py ├── utils │ ├── __init__.py │ ├── cli.py │ ├── echo_node.py │ ├── ethereum_clients.py │ ├── filters.py │ ├── gas_reserve.py │ ├── http.py │ ├── migrations │ │ └── v16_to_v17.py │ ├── namehash │ │ └── namehash.py │ ├── notifying_queue.py │ ├── rns.py │ ├── rsk_gas_price_strategy │ │ ├── __init__.py │ │ └── rsk_gas_price_strategy.py │ ├── runnable.py │ ├── serialization.py │ ├── signer.py │ ├── signing.py │ ├── smart_contracts.py │ ├── solc.py │ ├── timeout.py │ ├── typing.py │ └── upgrades.py └── waiting.py ├── raiden_errors_key.gpg ├── readthedocs.yml ├── requirements-dev.txt ├── requirements-docs.txt ├── requirements-lint.txt ├── requirements.txt ├── setup.cfg ├── setup.py ├── snap └── snapcraft.yaml ├── tools ├── __init__.py ├── check_circleci_config.py ├── config_builder.py ├── debugging │ ├── json-log-to-html.py │ ├── migrate_db.py │ └── replay_wal.py ├── deploy.sh ├── dummy_resolver_server.py ├── eth_auth_provider.py2 ├── gas_cost_measures.py ├── genesis_builder.py ├── join-contracts.py ├── parallel_tests.sh ├── process_results.py ├── pyinstaller_hooks │ ├── hook-Crypto.py │ ├── hook-cytoolz.py │ ├── hook-eth_hash.py │ ├── hook-gevent.py │ ├── hook-raiden.py │ ├── hook-raiden_contracts.py │ ├── hook-raiden_webui.py │ ├── runtime_encoding.py │ ├── runtime_gevent_monkey.py │ └── runtime_raiden_contracts.py ├── pylint │ ├── __init__.py │ ├── assert_checker.py │ └── gevent_checker.py ├── scenario-player │ ├── README.rst │ ├── example-scenarios │ │ ├── scenario-basic.yaml │ │ └── scenario-example-v2.yaml │ ├── requirements.txt │ └── scenario_player │ │ ├── __init__.py │ │ ├── __main__.py │ │ ├── exceptions.py │ │ ├── main.py │ │ ├── node_support.py │ │ ├── runner.py │ │ ├── tasks │ │ ├── base.py │ │ ├── channels.py │ │ ├── execution.py │ │ ├── raiden_api.py │ │ ├── raiden_node.py │ │ └── token_network.py │ │ ├── ui.py │ │ └── utils.py ├── startcluster.py ├── test_and_report.sh ├── testnet │ ├── .gitignore │ ├── .terraform │ │ └── terraform.tfstate │ ├── Makefile │ ├── README.rst │ ├── ansible.cfg │ ├── data.tf │ ├── files │ │ ├── dockerfiles │ │ │ ├── empty │ │ │ │ └── Dockerfile │ │ │ ├── geth-testnet │ │ │ │ ├── Dockerfile │ │ │ │ └── run.py │ │ │ ├── mkkeystore │ │ │ │ ├── Dockerfile │ │ │ │ └── mkkey.py │ │ │ ├── raiden │ │ │ │ ├── Dockerfile │ │ │ │ ├── raiden │ │ │ │ ├── raiden_echo_node │ │ │ │ └── run_raiden.py │ │ │ └── scenario_player │ │ │ │ └── Dockerfile │ │ └── templates │ │ │ └── eth_addresses.j2 │ ├── group_vars │ │ └── all.yml │ ├── inventory │ │ └── inventory.sh │ ├── keys │ │ └── .gitignore │ ├── library │ │ └── docker_facts │ ├── main.tf │ ├── output.tf │ ├── playbook-get_eth_addresses.yml │ ├── playbook-remove_datadir.yml │ ├── playbook-testnet.yml │ ├── roles │ │ ├── data_volume │ │ │ └── tasks │ │ │ │ └── main.yml │ │ ├── docker │ │ │ └── tasks │ │ │ │ └── main.yml │ │ ├── eth_node │ │ │ ├── meta │ │ │ │ └── main.yml │ │ │ └── tasks │ │ │ │ └── main.yml │ │ ├── hostname │ │ │ ├── tasks │ │ │ │ └── main.yml │ │ │ └── templates │ │ │ │ └── hostname.j2 │ │ ├── hosts_file │ │ │ ├── tasks │ │ │ │ └── main.yml │ │ │ └── templates │ │ │ │ └── hosts.j2 │ │ ├── keystore │ │ │ ├── defaults │ │ │ │ └── main.yml │ │ │ ├── tasks │ │ │ │ └── main.yml │ │ │ ├── templates │ │ │ │ └── password.j2 │ │ │ └── vars │ │ │ │ └── main.yml │ │ ├── logstash │ │ │ ├── files │ │ │ │ └── logstash.conf │ │ │ ├── meta │ │ │ │ └── main.yml │ │ │ ├── tasks │ │ │ │ └── main.yml │ │ │ └── vars │ │ │ │ └── main.yml │ │ ├── motd_info │ │ │ ├── tasks │ │ │ │ └── main.yml │ │ │ └── templates │ │ │ │ └── 99-nodes.j2 │ │ ├── raiden │ │ │ ├── meta │ │ │ │ └── main.yml │ │ │ └── tasks │ │ │ │ └── main.yml │ │ ├── ssh_keys │ │ │ ├── tasks │ │ │ │ └── main.yml │ │ │ └── templates │ │ │ │ └── authorized_keys.j2 │ │ └── traefik │ │ │ ├── tasks │ │ │ └── main.yml │ │ │ ├── templates │ │ │ ├── rules.toml.j2 │ │ │ └── traefik.toml.j2 │ │ │ └── vars │ │ │ └── main.yml │ └── variables.tf └── transfer_eth.py └── tox.ini /.bumpversion_client.cfg: -------------------------------------------------------------------------------- 1 | [bumpversion] 2 | 3 | current_version = 0.100.3 4 | 5 | commit = True 6 | tag = False 7 | 8 | [bumpversion:file:setup.py] 9 | serialize = {major}.{minor}.{patch} 10 | 11 | [bumpversion:file:docs/conf.py] 12 | serialize = {major}.{minor}.{patch} 13 | -------------------------------------------------------------------------------- /.circleci/conditional_skip.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Seems that circle calls this script with -e and we don't want 4 | # grep failure to stop the build 5 | set +e 6 | 7 | SKIP_TAG="\[skip tests\]" 8 | 9 | if [[ ! -z ${CIRCLE_TAG} ]]; then 10 | # TAG build - never skip those 11 | exit 0 12 | fi 13 | 14 | if [[ -a ~/.local/BASE_COMMIT ]]; then 15 | # The is a PR and we know the base commit (see fetch_pr_base_commit.sh) 16 | LOG_RANGE="$(cat ~/.local/BASE_COMMIT)..${CIRCLE_SHA1}" 17 | else 18 | # Otherwise just look at the HEAD commit 19 | LOG_RANGE="-1" 20 | fi 21 | 22 | git log --pretty="- %h %B" ${LOG_RANGE} | grep "${SKIP_TAG}" 23 | 24 | if [[ ${PIPESTATUS[1]} == 0 ]]; then 25 | echo Skip tag found - skipping build 26 | circleci step halt 27 | fi 28 | set -e 29 | -------------------------------------------------------------------------------- /.circleci/fetch_geth_parity_solc.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | set -x 5 | 6 | if [[ -z ${LOCAL_BASE} ]]; then 7 | LOCAL_BASE=~/.local 8 | fi 9 | 10 | GETH_PATH="${LOCAL_BASE}/bin/geth-${OS_NAME}-${GETH_VERSION}" 11 | if [[ ! -x ${GETH_PATH} ]]; then 12 | mkdir -p ${LOCAL_BASE}/bin 13 | TEMP=$(mktemp -d 2>/dev/null || mktemp -d -t 'gethtmp') 14 | pushd ${TEMP} 15 | GETH_URL_VAR="GETH_URL_${OS_NAME}" 16 | curl -o geth.tar.gz ${!GETH_URL_VAR} 17 | tar xzf geth.tar.gz 18 | cd geth*/ 19 | install -m 755 geth ${GETH_PATH} 20 | fi 21 | ln -sf ${GETH_PATH} ${LOCAL_BASE}/bin/geth 22 | 23 | PARITY_PATH="${LOCAL_BASE}/bin/parity-${OS_NAME}-${PARITY_VERSION}" 24 | if [[ ! -x ${PARITY_PATH} ]]; then 25 | mkdir -p ${LOCAL_BASE}/bin 26 | PARITY_URL_VAR="PARITY_URL_${OS_NAME}" 27 | curl -L ${!PARITY_URL_VAR} > ${PARITY_PATH} 28 | chmod 775 ${PARITY_PATH} 29 | fi 30 | ln -sf ${PARITY_PATH} ${LOCAL_BASE}/bin/parity 31 | 32 | # Only deal with solc for Linux since it's only used for testing 33 | if [[ ${OS_NAME} != "LINUX" ]]; then 34 | exit 0 35 | fi 36 | 37 | SOLC_PATH="${LOCAL_BASE}/bin/solc-${OS_NAME}-${SOLC_VERSION}" 38 | if [[ ! -x ${SOLC_PATH} ]]; then 39 | mkdir -p ${LOCAL_BASE}/bin 40 | SOLC_URL_VAR="SOLC_URL_${OS_NAME}" 41 | curl -L ${!SOLC_URL_VAR} > ${SOLC_PATH} 42 | chmod 775 ${SOLC_PATH} 43 | fi 44 | ln -sf ${SOLC_PATH} ${LOCAL_BASE}/bin/solc 45 | -------------------------------------------------------------------------------- /.circleci/fetch_geth_solc.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | set -x 5 | 6 | GETH_PATH="${HOME}/.local/bin/geth-${OS_NAME}-${GETH_VERSION}" 7 | if [[ ! -x ${GETH_PATH} ]]; then 8 | mkdir -p ${HOME}/.local/bin 9 | TEMP=$(mktemp -d 2>/dev/null || mktemp -d -t 'gethtmp') 10 | pushd ${TEMP} 11 | GETH_URL_VAR="GETH_URL_${OS_NAME}" 12 | wget -O geth.tar.gz ${!GETH_URL_VAR} 13 | tar xzf geth.tar.gz 14 | cd geth*/ 15 | install -m 755 geth ${GETH_PATH} 16 | fi 17 | ln -sf ${GETH_PATH} ${HOME}/.local/bin/geth 18 | 19 | SOLC_PATH="${HOME}/.local/bin/solc-${OS_NAME}-${SOLC_VERSION}" 20 | if [[ ! -x ${SOLC_PATH} ]]; then 21 | mkdir -p ${HOME}/.local/bin 22 | SOLC_URL_VAR="SOLC_URL_${OS_NAME}" 23 | curl -L ${!SOLC_URL_VAR} > ${SOLC_PATH} 24 | chmod 775 ${SOLC_PATH} 25 | fi 26 | ln -sf ${SOLC_PATH} ${HOME}/.local/bin/solc 27 | -------------------------------------------------------------------------------- /.circleci/fetch_pr_base_commit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ -n "${CIRCLE_PR_NUMBER}" ]]; then 4 | # If this is a PR get the base commit from the GitHub API 5 | PR_DETAILS_URL="https://api.github.com/repos/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/pulls/${CIRCLE_PR_NUMBER}" 6 | BASE_COMMIT=$(curl ${PR_DETAILS_URL} | jq -r .base.sha) 7 | if [[ ${BASE_COMMIT} =~ ^[0-9a-zA-Z]{40}$ ]]; then 8 | echo ${BASE_COMMIT} > ~/.local/BASE_COMMIT 9 | fi 10 | fi 11 | -------------------------------------------------------------------------------- /.circleci/fetch_ssh_hostkey.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -ex 4 | 5 | HOST="$1" 6 | FINGERPRINT="$2" 7 | 8 | PUBKEY=$(mktemp) 9 | 10 | ssh-keyscan -H ${HOST} > ${PUBKEY} 2>/dev/null 11 | 12 | if [[ $(ssh-keygen -l -f ${PUBKEY} | cut -d ' ' -f 2) != ${FINGERPRINT} ]]; then 13 | echo "Warning fingerprint mismatch while fetching public key for ${HOST}" 14 | exit 1 15 | fi 16 | 17 | cat ${PUBKEY} >> ~/.ssh/known_hosts 18 | -------------------------------------------------------------------------------- /.circleci/get_archive_tag.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ex 3 | 4 | if [[ ! -z ${CIRCLE_TAG} ]]; then 5 | export ARCHIVE_TAG=${CIRCLE_TAG} 6 | else 7 | DATE=$(date +%Y-%m-%dT%H-%M-%S) 8 | RAIDEN_VERSION=$(python setup.py --version) 9 | export ARCHIVE_TAG="nightly-${DATE}-v${RAIDEN_VERSION}" 10 | fi 11 | 12 | echo "export ARCHIVE_TAG=${ARCHIVE_TAG}" >> ${BASH_ENV} 13 | 14 | set +ex 15 | -------------------------------------------------------------------------------- /.circleci/upload_to_s3.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -ex 4 | 5 | access_key=$1 6 | secret_key=$2 7 | dir=$3 8 | bucket=$4 9 | endpoint=$5 10 | 11 | s3cmd \ 12 | --access_key ${access_key} \ 13 | --secret_key ${secret_key} \ 14 | --host ${endpoint} \ 15 | --host-bucket "%(bucket)s.${endpoint}" \ 16 | --no-progress \ 17 | --stats \ 18 | --no-delete-removed \ 19 | --guess-mime-type \ 20 | --acl-public \ 21 | sync \ 22 | ${dir} \ 23 | s3://${bucket}/ 24 | -------------------------------------------------------------------------------- /.codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | status: 3 | project: no 4 | patch: no 5 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | tools/testnet/.terraform/plugins 3 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root=true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = false 6 | charset = utf-8 7 | indent_style = space 8 | indent_size = 4 9 | 10 | [*.{js,py}] 11 | trim_trailing_whitespace = true 12 | 13 | [*.{yml,yaml,json}] 14 | indent_size = 2 15 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.sol linguist-language=Solidity -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/critical_vulnerability_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Critical Vulnerability Report 3 | about: Critical vulnerability reports about the Raiden Network 4 | --- 5 | 6 | # DO NOT use Github 7 | 8 | If the issue you want to report is a critical vulnerability, something that may lead to lock up or loss of funds for Raiden users, then please do not use the public issue tracker. 9 | 10 | Instead send an email with a detailed report to bounty@raiden.network. 11 | 12 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature Request 3 | about: Requesting new features to be added to either Raiden backend or UI 4 | --- 5 | 6 | ## Abstract 7 | 8 | Please describe by example what problem you see in the current Raiden Network implementation that you would like addressed. 9 | 10 | ## Motivation 11 | 12 | In this section please describe how you propose to address the problem you described earlier. Try to include example use cases that showcase the value of your proposal. 13 | 14 | ## Specification 15 | 16 | If the feature is technical in nature please write as detailed as possible a specification of what needs to be built. 17 | 18 | ## Backwards Compatibility 19 | 20 | If the feature is technical in nature and introduces changes to the Raiden Protocol, then please use this section to describe how backwards compatibility with the previous version of the protocol can be achieved. 21 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/bugfix.md: -------------------------------------------------------------------------------- 1 | Fixes: # 2 | 3 | ## Description 4 | 5 | Please, detail the root cause of the bug and how this PR fixes it. 6 | 7 | ## PR review check list 8 | 9 | Quality check list that cannot be automatically verified. 10 | 11 | - [ ] Safety 12 | - [ ] The changes respect the necessary conditions for safety (https://raiden-network-specification.readthedocs.io/en/latest/smart_contracts.html#protocol-values-constraints) 13 | - [ ] Code quality 14 | - [ ] Error conditions are handled 15 | - [ ] Exceptions are propagated to the correct parent greenlet 16 | - [ ] Exceptions are correctly classified as recoverable or unrecoverable 17 | - [ ] Compatibility 18 | - [ ] State changes are forward compatible 19 | - [ ] Transport messages are backwards and forward compatible 20 | - [ ] Regression test for the bug 21 | - [ ] Properly covers the bug 22 | - [ ] If an integration test is used, it could not be written as a unit test 23 | - [ ] Commits 24 | - [ ] Have good messages 25 | - [ ] Squashed unecessary commits 26 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/feature.md: -------------------------------------------------------------------------------- 1 | ## Description 2 | 3 | Please, describe the feature this PR is introducing. 4 | 5 | ## PR review check list 6 | 7 | Quality check list that cannot be automatically verified. 8 | 9 | - [ ] Safety 10 | - [ ] The changes respect the necessary conditions for safety (https://raiden-network-specification.readthedocs.io/en/latest/smart_contracts.html#protocol-values-constraints) 11 | - [ ] Code quality 12 | - [ ] Error conditions are handled 13 | - [ ] Exceptions are propagated to the correct parent greenlet 14 | - [ ] Exceptions are correctly classified as recoverable or unrecoverable 15 | - [ ] Compatibility 16 | - [ ] State changes are forward compatible 17 | - [ ] Transport messages are backwards and forward compatible 18 | - [ ] Tests for the new code 19 | - [ ] Properly covers the new code 20 | - [ ] If an integration test is used, it could not be written as a unit test 21 | - [ ] Commits 22 | - [ ] Have good messages 23 | - [ ] Squashed unecessary commits 24 | - [ ] A changelog entry was added 25 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/refactoring.md: -------------------------------------------------------------------------------- 1 | ## Description 2 | 3 | Please, describe why the refactoring is necessary. What are its pros and cons 4 | in respect to the previous code, and other possible design choices. 5 | 6 | ## PR review check list 7 | 8 | Quality check list that cannot be automatically verified. 9 | 10 | - [ ] Safety 11 | - [ ] The changes respect the necessary conditions for safety (https://raiden-network-specification.readthedocs.io/en/latest/smart_contracts.html#protocol-values-constraints) 12 | - [ ] Code quality 13 | - [ ] Error conditions are handled 14 | - [ ] Exceptions are propagated to the correct parent greenlet 15 | - [ ] Exceptions are correctly classified as recoverable or unrecoverable 16 | - [ ] Compatibility 17 | - [ ] State changes are forward compatible 18 | - [ ] Transport messages are backwards and forward compatible 19 | - [ ] Tests for the new code 20 | - [ ] Properly covers the new code 21 | - [ ] If an integration test is used, it could not be written as a unit test 22 | - [ ] Commits 23 | - [ ] Have good messages 24 | - [ ] Squashed unecessary commits 25 | - [ ] Docummented the design choices 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # ignore private keys 2 | *.pem 3 | 4 | # Byte-compiled / optimized / DLL files 5 | __pycache__/ 6 | *.py[cod] 7 | 8 | # C extensions 9 | *.so 10 | 11 | # Distribution / packaging 12 | .Python 13 | env/ 14 | devenv/ 15 | build/ 16 | develop-eggs/ 17 | dist/ 18 | downloads/ 19 | eggs/ 20 | .eggs/ 21 | lib/ 22 | lib64/ 23 | parts/ 24 | sdist/ 25 | var/ 26 | *.egg-info/ 27 | .installed.cfg 28 | *.egg 29 | 30 | 31 | # PyInstaller 32 | # Usually these files are written by a python script from a template 33 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 34 | *.manifest 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *,cover 49 | .pytest_cache/ 50 | mypy-out.txt 51 | 52 | # Pyenv 53 | .python-version 54 | 55 | # mypy 56 | .mypy_cache 57 | 58 | # Translations 59 | *.mo 60 | *.pot 61 | 62 | # Django stuff: 63 | *.log 64 | 65 | # Sphinx documentation 66 | docs/_build/ 67 | 68 | # PyBuilder 69 | target/ 70 | 71 | # never check in .static-abi.json files 72 | *.static-abi.json 73 | 74 | # editors 75 | .idea 76 | .vscode 77 | 78 | # Our logs 79 | raiden-debug_*.log 80 | 81 | # direnv virtual envs 82 | .direnv 83 | .envrc 84 | 85 | # venvs 86 | venv/ 87 | clientEnv/ 88 | 89 | # test keystores 90 | keystores 91 | 92 | # ui autogenerated costants 93 | raiden/api/webui/static/endpointConfig.js 94 | 95 | # raiden logs 96 | raiden/raiden-* 97 | -------------------------------------------------------------------------------- /.pylint.rc: -------------------------------------------------------------------------------- 1 | [MASTER] 2 | jobs=4 3 | persistent=yes 4 | suggestion-mode=yes 5 | unsafe-load-any-extension=no 6 | 7 | # Blacklist files or directories (basenames, not paths) 8 | ignore= 9 | 10 | # blacklist files or directories by regex (basenames, not paths) 11 | ignore-patterns= 12 | 13 | [EXCEPTIONS] 14 | 15 | overgeneral-exceptions=Exception,RaidenUnrecoverableError 16 | 17 | [BASIC] 18 | 19 | bad-names=foo,bar,baz,toto,tutu,tata 20 | good-names=i,j,k,_ 21 | 22 | [LOGGING] 23 | 24 | logging-modules=logging,structlog 25 | 26 | [MESSAGES CONTROL] 27 | 28 | disable=all 29 | enable=no-value-for-parameter,too-many-format-args,no-member,bad-except-order,redefined-builtin,bad-continuation,unused-variable 30 | 31 | [REPORTS] 32 | 33 | reports=no 34 | score=no 35 | 36 | [FORMAT] 37 | 38 | expected-line-ending-format=LF 39 | ignore-long-lines=^\s*(# )??$ 40 | max-line-length=100 41 | max-module-lines=1000 42 | no-space-check=trailing-comma 43 | 44 | [VARIABLES] 45 | 46 | callbacks=cb_,_cb 47 | dummy-variables-rgx=_ 48 | ignored-argument-names=_.* 49 | 50 | [TYPECHECK] 51 | 52 | contextmanager-decorators=contextlib.contextmanager 53 | 54 | # List of class names for which member attributes should not be checked 55 | ignored-classes= 56 | 57 | # List of module names for which member attributes should not be checked 58 | ignored-modules= 59 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015-2019 Brainbot Labs Est. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Lumino.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/Lumino.png -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include README.rst 2 | include requirements.txt 3 | include constraints.txt 4 | -------------------------------------------------------------------------------- /None.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/None.lock -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/README.rst -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "networks": { 3 | "test_net": { 4 | "network_id": 31, 5 | "name": "tesnet", 6 | "endpoint_registry": "0x6BEb99b6eCac8E4E2EdeC141042135D0dD8F15c1", 7 | "secret_registry": "0x59e1344572EC42BB0BB95046E07d6509Bc737b57", 8 | "token_network_registry": "0x7385f5c9Fb5D5cd11b689264756A847359d2FDc7" 9 | }, 10 | "main_net": { 11 | "network_id": 30, 12 | "name": "mainet", 13 | "endpoint_registry": "0xDd9Df254972a61898E125FDd3Cbe235Bec565f8e", 14 | "secret_registry": "0x30aabDd1f2A31c5faEDD8B9328F3294a7D7D7DF7", 15 | "token_network_registry": "0x5bE08F3AAD3AB1214be82f3E4FFD0B214Fd4653B" 16 | } 17 | }, 18 | "project": { 19 | "version": "0.0.2" 20 | } 21 | } -------------------------------------------------------------------------------- /config_sample.toml: -------------------------------------------------------------------------------- 1 | #keystore-path = 2 | #datadir = "~/.raiden" 3 | 4 | ## Ethereum address to use, must exist in `keystore-path` 5 | #address = 6 | #password-file = 7 | 8 | #secret-registry-contract-address = "0x7862eF1296EeF5Fa55ef056c0cB03FF8D4d49Cf8" 9 | #tokennetwork-registry-contract-address = "0x66eea3159A01d134DD64Bfe36fde4bE9ED9c1695" 10 | #endpoint-registry-contract-address = "0x1E3941d8c05ffFA7466216480209240cc26ea577" 11 | 12 | #console = false 13 | 14 | ## Transport system to use 'udp' or 'matrix' 15 | #transport = "udp" 16 | 17 | ## Available networks: 18 | ## mainnet: 1 19 | ## ropsten: 3 20 | ## rinkeby: 4 21 | ## kovan: 42 22 | #network-id = 3 23 | 24 | #sync-check = true 25 | #gas-price = 26 | #eth-rpc-endpoint = "127.0.0.1:8545" 27 | #listen-address = "0.0.0.0:38647" 28 | #max-unresponsive-time = 30 29 | #send-ping-time = 60 30 | 31 | ## Available nat methods: 32 | ## auto - Try UPnP, then STUN, fallback to none 33 | ## upnp - Try UPnP, fallback to none 34 | ## stun - Try STUN, fallback to none 35 | ## none - Use the local interface address 36 | # nat = "auto" 37 | 38 | ## Valid values: 39 | ## auto - automatically select a suitable homeserver 40 | ## A URL pointing to a Raiden matrix homeserver 41 | #matrix-server = "auto" 42 | 43 | #log-file = 44 | #log-json = false 45 | 46 | #rpc = true 47 | #rpccorsdomain = "http://localhost:*/*" 48 | #api-address = "127.0.0.1:5001" 49 | #web-ui = true 50 | 51 | #[log-config] 52 | #"" = "INFO" 53 | -------------------------------------------------------------------------------- /constraints.txt: -------------------------------------------------------------------------------- 1 | aniso8601==3.0.2 2 | appnope==0.1.0 3 | asn1crypto==0.24.0 4 | attrdict==2.0.0 5 | cachetools==2.1.0 6 | certifi==2018.8.24 7 | cffi==1.11.5 8 | chardet==3.0.4 9 | Click==7.0 10 | coincurve==11.0.0 11 | colorama==0.3.9 12 | cytoolz==0.9.0.1 13 | decorator==4.3.0 14 | Deprecated==1.2.5 15 | eth-abi==1.3.0 16 | eth-account==0.3.0 17 | eth-hash==0.2.0 18 | eth-keyfile==0.5.1 19 | eth-keys==0.2.1 20 | eth-rlp==0.1.2 21 | eth-typing==2.1.0 22 | eth-utils==1.4.1 23 | filelock==3.0.8 24 | Flask-Cors==3.0.6 25 | Flask-RESTful==0.3.6 26 | Flask==1.0.2 27 | gevent==1.3.6 28 | gnureadline==6.3.8;platform_system=="Darwin" 29 | greenlet==0.4.15 30 | hexbytes==0.1.0 31 | idna==2.7 32 | ipython-genutils==0.2.0 33 | ipython==4.2.1 34 | itsdangerous==0.24 35 | Jinja2==2.10 36 | lru-dict==1.1.6 37 | MarkupSafe==1.1.0 38 | marshmallow-polyfield==3.2 39 | marshmallow==2.15.4 40 | matrix-client==0.3.2 41 | miniupnpc==2.0.2 42 | mirakuru==1.0.0 43 | mypy-extensions==0.4.1 44 | netifaces==0.10.7 45 | networkx==2.1 46 | parsimonious==0.8.0 47 | pexpect==4.6.0 48 | pickleshare==0.7.4 49 | psutil==5.6.6 50 | ptyprocess==0.6.0 51 | py-geth==2.1.0 52 | py-solc==3.2.0 53 | pycparser==2.18 54 | pycryptodome==3.6.6 55 | pysha3==1.0.2 56 | pystun-patched-for-raiden==0.1.0 57 | pytoml==0.1.19 58 | pytz==2018.5 59 | raiden-contracts==0.19.1 60 | raiden-webui==0.8.0 61 | requests==2.20.0 62 | rlp==1.1.0 63 | semantic-version==2.6.0 64 | semver==2.8.1 65 | simplegeneric==0.8.1 66 | six==1.11.0 67 | structlog==18.2.0 68 | toolz==0.9.0 69 | traitlets==4.3.2 70 | urllib3==1.23 71 | webargs==5.1.3 72 | websockets==6.0 73 | Werkzeug==0.14.1 74 | wrapt==1.11.1 75 | -------------------------------------------------------------------------------- /definitions.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | # This is your Project Root 4 | ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | 2 | # This will build the latest master 3 | # 4 | # we use an intermediate image to build this image. it will make the resulting 5 | # image a bit smaller. 6 | # 7 | # you can build the image with: 8 | # 9 | # docker build . -t raiden 10 | 11 | FROM python:3 as builder 12 | 13 | # use --build-arg RAIDENVERSION=v0.0.3 to build a specific (tagged) version 14 | ARG REPO=raiden-network/raiden 15 | ARG RAIDENVERSION=master 16 | 17 | # This is a "hack" to automatically invalidate the cache in case there are new commits 18 | ADD https://api.github.com/repos/${REPO}/commits/${RAIDENVERSION} /dev/null 19 | 20 | # clone raiden repo + install dependencies 21 | RUN git clone -b ${RAIDENVERSION} https://github.com/${REPO} /app/raiden 22 | 23 | RUN python3 -m venv /opt/venv 24 | 25 | RUN /opt/venv/bin/pip3 install -c /app/raiden/constraints.txt -r /app/raiden/requirements.txt /app/raiden 26 | 27 | 28 | FROM python:3-slim as runner 29 | 30 | COPY --from=builder /opt/venv /opt/venv 31 | 32 | EXPOSE 5001 33 | 34 | ENTRYPOINT ["/opt/venv/bin/python3", "-m", "raiden"] 35 | -------------------------------------------------------------------------------- /docker/build.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.7 2 | 3 | # these are defined in .travis.yml and passed here in the makefile 4 | ARG SOLC_URL_LINUX 5 | ARG GETH_URL_LINUX 6 | 7 | # install dependencies 8 | RUN apt-get update 9 | RUN apt-get install -y git-core wget xz-utils libgmp-dev 10 | 11 | RUN wget -nv -O /usr/bin/solc ${SOLC_URL_LINUX} && \ 12 | chmod +x /usr/bin/solc 13 | RUN wget -nv -O /tmp/geth.tar.gz ${GETH_URL_LINUX} && \ 14 | cd /tmp && \ 15 | tar xf geth.tar.gz && \ 16 | mv geth-linux-amd64-*/geth /usr/bin/geth && \ 17 | rm geth.tar.gz 18 | 19 | 20 | ADD requirements*.txt /tmp/ 21 | ADD constraints.txt /tmp/ 22 | WORKDIR /tmp 23 | 24 | RUN pip install -U 'pip<19.0.0' setuptools setuptools_scm 25 | RUN pip install -r requirements.txt -c constraints.txt 26 | RUN pip install pyinstaller 27 | 28 | ADD . /raiden 29 | 30 | WORKDIR /raiden 31 | RUN git fetch --tags | true 32 | 33 | 34 | # build contracts and web_ui 35 | RUN python setup.py build 36 | 37 | # install raiden 38 | RUN pip install -c constraints.txt . 39 | 40 | 41 | ARG ARCHIVE_TAG 42 | ARG ARCHITECTURE_TAG 43 | 44 | # build pyinstaller package 45 | RUN pyinstaller --noconfirm --clean raiden.spec 46 | 47 | # pack result to have a unique name to get it out of the container later 48 | RUN export FILE_TAG=${ARCHIVE_TAG:-v$(python setup.py --version)} && \ 49 | cd dist && \ 50 | tar -cvzf ./raiden-${FILE_TAG}-linux-${ARCHITECTURE_TAG}.tar.gz raiden-${FILE_TAG}-linux-${ARCHITECTURE_TAG} && \ 51 | mv raiden-${FILE_TAG}-linux-${ARCHITECTURE_TAG}.tar.gz .. 52 | -------------------------------------------------------------------------------- /docker/raiden.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=Raiden 3 | Version=XXVERSIONXX 4 | Exec=raiden 5 | Icon=raiden 6 | Type=Application 7 | StartupNotify=true 8 | -------------------------------------------------------------------------------- /docs/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/docs/.DS_Store -------------------------------------------------------------------------------- /docs/0.0.1/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/docs/0.0.1/.DS_Store -------------------------------------------------------------------------------- /docs/0.0.1/Lumino.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/docs/0.0.1/Lumino.png -------------------------------------------------------------------------------- /docs/0.0.1/README.md: -------------------------------------------------------------------------------- 1 | # RIF Lumino Network Documentation 2 | 3 | 4 | ![Lumino Network](Lumino.png?raw=true "RIF Lumino Network") 5 | 6 | 7 | ## Install Lumino 8 | 9 | - [Install in Ubuntu](install_ubuntu.md) 10 | - [Install in MacOS](install_macos.md) 11 | 12 | ## Lumino Contracts 13 | 14 | The following are the addresses of the set of contracts for Lumino Network 15 | 16 | | Contract | TestNet | MainNet | 17 | |-----------------------------------------|--------------------------------------------|----------------| 18 | | `$TOKENNETWORK_REGISTRY_CONTRACT_ADDRESS` | TBD | 0x59eC7Ced1e1ee2e4ccC74F197fB680D8f9426B96 | 19 | | `$SECRET_REGISTRY_CONTRACT_ADDRESS` | TBD | 0x4Dea623Ae7c5cb1F4aF9B46721D9a72d93C42BE9 | 20 | | `$ENDPOINT_REGISTRY_CONTRACT_ADDRESS` | TBD | 0x7d1E6f17baa2744B5213b697ae4C1D287bB10df0 | 21 | -------------------------------------------------------------------------------- /docs/0.0.2/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/docs/0.0.2/.DS_Store -------------------------------------------------------------------------------- /docs/0.0.2/Lumino.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/docs/0.0.2/Lumino.png -------------------------------------------------------------------------------- /docs/0.0.2/README.md: -------------------------------------------------------------------------------- 1 | # RIF Lumino Network Documentation 2 | 3 | 4 | ![Lumino Network](Lumino.png?raw=true "RIF Lumino Network") 5 | 6 | 7 | ## Install Lumino 8 | 9 | - [Install in Ubuntu](install_ubuntu.md) 10 | - [Install in MacOS](install_macos.md) 11 | 12 | ## Lumino Contracts 13 | 14 | The following are the addresses of the set of contracts for Lumino Network 15 | 16 | | Contract | TestNet | MainNet | 17 | |-----------------------------------------|--------------------------------------------|----------------| 18 | | `$TOKENNETWORK_REGISTRY_CONTRACT_ADDRESS` | TBD | 0x59eC7Ced1e1ee2e4ccC74F197fB680D8f9426B96 | 19 | | `$SECRET_REGISTRY_CONTRACT_ADDRESS` | TBD | 0x4Dea623Ae7c5cb1F4aF9B46721D9a72d93C42BE9 | 20 | | `$ENDPOINT_REGISTRY_CONTRACT_ADDRESS` | TBD | 0x7d1E6f17baa2744B5213b697ae4C1D287bB10df0 | 21 | 22 | -------------------------------------------------------------------------------- /docs/0.0.4/Lumino.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/docs/0.0.4/Lumino.png -------------------------------------------------------------------------------- /docs/0.0.4/README.md: -------------------------------------------------------------------------------- 1 | # RIF Lumino Network 2 | 3 | 4 | ![Lumino Network](Lumino.png?raw=true "RIF Lumino Network") 5 | 6 | 7 | ## Install your own Lumino Node 8 | 9 | * [Install on Ubuntu](docs/0.0.3/install_ubuntu.md) 10 | * [Install on MacOS](docs/0.0.3/install_macos.md) 11 | 12 | ## Lumino Contracts 13 | 14 | The following are the addresses of the set of contracts for Lumino Network 15 | 16 | 17 | 18 | | Contract | TestNet | MainNet | 19 | |-----------------------------------------|--------------------------------------------|----------------| 20 | | `$TOKENNETWORK_REGISTRY_CONTRACT_ADDRESS` | 0x7385f5c9Fb5D5cd11b689264756A847359d2FDc7 | 0x5bE08F3AAD3AB1214be82f3E4FFD0B214Fd4653B | 21 | | `$SECRET_REGISTRY_CONTRACT_ADDRESS` | 0x59e1344572EC42BB0BB95046E07d6509Bc737b57 | 0x30aabDd1f2A31c5faEDD8B9328F3294a7D7D7DF7 | 22 | | `$ENDPOINT_REGISTRY_CONTRACT_ADDRESS` | 0x6BEb99b6eCac8E4E2EdeC141042135D0dD8F15c1 | 0xDd9Df254972a61898E125FDd3Cbe235Bec565f8e | 23 | 24 | 25 | If you want to create your own RIF Lumino network for development or custom use on private networks, please refer to [Lumino Contracts](https://github.com/rsksmart/lumino-contracts) 26 | 27 | 28 | 29 | ## Useful Links 30 | 31 | * [RIF Lumino Network](https://www.rifos.org/rif-lumino-network/) 32 | * [http://explorer.lumino.rifos.org/](https://explorer.lumino.rifos.org/) 33 | * [RIF Lumino Contracts](https://github.com/rsksmart/lumino-contracts) 34 | * [RIF Lumino Web](https://github.com/rsksmart/lumino-web) 35 | * [RIF Lumino Explorer](https://github.com/rsksmart/lumino-explorer) 36 | -------------------------------------------------------------------------------- /docs/Token-Swap.md: -------------------------------------------------------------------------------- 1 | # Scenario: Token swap 2 | - User Alice wants to exchange N tokens X for M tokens Y with user Charlie 3 | - Alice and Charlie have channels for both tokens with enough capacity 4 | 5 | **Solution:** 6 | 7 | Two token transfers with same hashlock allow to atomically swap tokens with a 8 | predetermined ration. See and `MakerTokenSwapTask` and `TakerTokenSwapTask` in 9 | the code. 10 | -------------------------------------------------------------------------------- /docs/_static/sphinxcontrib-httpexample.css: -------------------------------------------------------------------------------- 1 | .http-example .caption, 2 | .section ul .http-example .caption { 3 | display: inline-block; 4 | cursor: pointer; 5 | padding: 0.5em 1em; 6 | margin: 0; 7 | } 8 | .http-example .caption.selected { 9 | font-weight: bold; 10 | background-color: #fff; 11 | border: 1px solid #e1e4e5; 12 | border-bottom: 1px solid white; 13 | } 14 | .http-example div[class^='highlight'] { 15 | margin-top: -1px; 16 | } 17 | .http-example div[class^='highlight'] pre { 18 | white-space: normal; 19 | } 20 | .http-example div.highlight-bash pre { 21 | white-space: pre-wrap; 22 | } 23 | .http-example-http div[class^='highlight'] pre, 24 | .http-example-response div[class^='highlight'] pre { 25 | white-space: pre; 26 | } 27 | -------------------------------------------------------------------------------- /docs/_static/sphinxcontrib-httpexample.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | var jQuery = window.jQuery || function() {}; 3 | 4 | jQuery(function($) { 5 | $('.http-example.container').each(function() { 6 | var $container = $(this), 7 | $blocks = $(this).children(), 8 | $captions = $(this).find('.caption'); 9 | $captions.each(function() { 10 | var $block = $(this).parent(); 11 | $(this).on('click', function() { 12 | $captions.removeClass('selected'); 13 | $(this).addClass('selected'); 14 | $blocks.hide(); 15 | $block.show(); 16 | }); 17 | $container.append($(this)); 18 | }); 19 | $container.append($blocks); 20 | $captions.first().click(); 21 | }); 22 | }); 23 | 24 | })(); 25 | -------------------------------------------------------------------------------- /docs/images/architecture_overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/docs/images/architecture_overview.png -------------------------------------------------------------------------------- /docs/images/channelsgraph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/docs/images/channelsgraph.png -------------------------------------------------------------------------------- /docs/images/merkletree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/docs/images/merkletree.png -------------------------------------------------------------------------------- /docs/images/pending_transfers_for_mediator.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/docs/images/pending_transfers_for_mediator.gif -------------------------------------------------------------------------------- /docs/images/raiden_webui_channels_page_screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/docs/images/raiden_webui_channels_page_screenshot.png -------------------------------------------------------------------------------- /docs/images/raiden_webui_landing_page_screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/docs/images/raiden_webui_landing_page_screenshot.png -------------------------------------------------------------------------------- /docs/images/raiden_webui_tokens_page_screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/docs/images/raiden_webui_tokens_page_screenshot.png -------------------------------------------------------------------------------- /docs/images/restore_wal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/docs/images/restore_wal.png -------------------------------------------------------------------------------- /docs/images/routing_a_transfer.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/docs/images/routing_a_transfer.gif -------------------------------------------------------------------------------- /docs/images/settle_pending_locks.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/docs/images/settle_pending_locks.gif -------------------------------------------------------------------------------- /docs/images/state_tasks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/docs/images/state_tasks.png -------------------------------------------------------------------------------- /docs/images/transfer_happy_case.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/docs/images/transfer_happy_case.gif -------------------------------------------------------------------------------- /docs/images/transfer_unhappy_case.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/docs/images/transfer_unhappy_case.gif -------------------------------------------------------------------------------- /docs/images/write_state_change_to_wal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/docs/images/write_state_change_to_wal.png -------------------------------------------------------------------------------- /docs/raiden.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/docs/raiden.png -------------------------------------------------------------------------------- /docs/trademarks.rst: -------------------------------------------------------------------------------- 1 | Trademark Attributions 2 | ########################## 3 | 4 | 5 | - MacOS® is a trademark of Apple Inc., registered in the U.S. and other countries. 6 | - Linux® is the registered trademark of Linus Torvalds in the U.S. and other countries. 7 | -------------------------------------------------------------------------------- /nix/envrc-nix-python: -------------------------------------------------------------------------------- 1 | use nix nix/shell.nix 2 | 3 | # Create a virtualenv and activate it. 4 | layout python -------------------------------------------------------------------------------- /nix/leveldb.nix: -------------------------------------------------------------------------------- 1 | { pkgs , stdenv, fetchFromGitHub }: 2 | 3 | stdenv.mkDerivation rec { 4 | name = "leveldb-${version}"; 5 | version = "1.21-pre"; 6 | 7 | src = fetchFromGitHub { 8 | owner = "google"; 9 | repo = "leveldb"; 10 | rev = "6caf73ad9dae0ee91873bcb39554537b85163770"; 11 | sha256 = "1djwnxmfbflvzqs2vzlxc9ms1yj2pd2dax5vr0xvws26xcdzd0ck"; 12 | }; 13 | 14 | buildInputs = [ pkgs.cmake ]; 15 | } 16 | -------------------------------------------------------------------------------- /nix/shell.nix: -------------------------------------------------------------------------------- 1 | with import ( 2 | builtins.fetchTarball { 3 | # To update 4 | # curl -sI https://nixos.org/channels/nixpkgs-unstable/nixexprs.tar.xz | awk '/Location:/ {print $2}' 5 | url = "https://d3g5gsiof5omrk.cloudfront.net/nixpkgs/nixpkgs-18.09pre146409.2391d1dbf31/nixexprs.tar.xz"; 6 | # To get the hash 7 | # nix-prefetch-url --unpack $url 8 | sha256 = "08iy7dlyy5f7w1npajrb5pi7gl6mwfjimkkpbcqmkz01bam9bq5x"; 9 | } 10 | ) { }; 11 | 12 | # plyvl requires leveldb >= 1.20 13 | let myLeveldb = callPackage ./leveldb.nix {}; 14 | 15 | in mkShell rec { 16 | 17 | # Might be needed on mac OS? If so, consider setting on darwin automatically. 18 | # LC_ALL="en_US.UTF-8"; 19 | 20 | # Cannot build wheel otherwise (zip 1980 issue). 21 | SOURCE_DATE_EPOCH="315532800"; 22 | 23 | buildInputs = [ 24 | libffi 25 | openssl 26 | gmp 27 | pkgconfig 28 | python36 29 | python36Packages.virtualenv 30 | solc 31 | myLeveldb 32 | libxml2 33 | libxslt 34 | go-ethereum 35 | gitMinimal 36 | nodejs-8_x 37 | ]; 38 | 39 | } 40 | -------------------------------------------------------------------------------- /pip-wheel-metadata/raiden.dist-info/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015-2019 Brainbot Labs Est. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /pip-wheel-metadata/raiden.dist-info/entry_points.txt: -------------------------------------------------------------------------------- 1 | [console_scripts] 2 | lumino = raiden.__main__:main 3 | 4 | -------------------------------------------------------------------------------- /pip-wheel-metadata/raiden.dist-info/top_level.txt: -------------------------------------------------------------------------------- 1 | raiden 2 | -------------------------------------------------------------------------------- /pylintrc: -------------------------------------------------------------------------------- 1 | [MASTER] 2 | jobs=4 3 | persistent=yes 4 | suggestion-mode=yes 5 | unsafe-load-any-extension=no 6 | load-plugins=tools.pylint.gevent_checker 7 | 8 | # Blacklist files or directories (basenames, not paths) 9 | ignore= 10 | 11 | # blacklist files or directories by regex (basenames, not paths) 12 | ignore-patterns= 13 | 14 | [EXCEPTIONS] 15 | 16 | overgeneral-exceptions=Exception,RaidenUnrecoverableError 17 | 18 | [BASIC] 19 | 20 | bad-names=foo,bar,baz,toto,tutu,tata 21 | good-names=i,j,k,_ 22 | 23 | [LOGGING] 24 | 25 | logging-modules=logging,structlog 26 | 27 | [MESSAGES CONTROL] 28 | 29 | disable=all 30 | enable= 31 | no-value-for-parameter, 32 | too-many-format-args, 33 | no-member, 34 | bad-except-order, 35 | redefined-builtin, 36 | unused-variable, 37 | no-self-use, 38 | import-self, 39 | gevent-joinall, 40 | useless-object-inheritance, 41 | unused-argument, 42 | unexpected-keyword-arg, 43 | expression-not-assigned, 44 | pointless-statement, 45 | unused-import, 46 | inconsistent-return-statements, 47 | reimported, 48 | too-many-function-args 49 | 50 | [REPORTS] 51 | 52 | reports=no 53 | score=no 54 | 55 | [FORMAT] 56 | 57 | expected-line-ending-format=LF 58 | ignore-long-lines=^\s*(# )??$ 59 | max-line-length=100 60 | max-module-lines=1000 61 | no-space-check=trailing-comma 62 | 63 | [VARIABLES] 64 | 65 | callbacks=cb_,_cb 66 | dummy-variables-rgx=_ 67 | ignored-argument-names=_.* 68 | 69 | [TYPECHECK] 70 | 71 | contextmanager-decorators=contextlib.contextmanager 72 | 73 | # List of class names for which member attributes should not be checked 74 | ignored-classes= 75 | 76 | # List of module names for which member attributes should not be checked 77 | ignored-modules= 78 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.black] 2 | line-length = 99 3 | target-version = ['py37'] 4 | include = '\.pyi?$' 5 | exclude = ''' 6 | /( 7 | \.git 8 | | \.mypy_cache 9 | | \.tox 10 | | \.venv 11 | | build 12 | | dist 13 | )/ 14 | ''' 15 | -------------------------------------------------------------------------------- /raiden/None: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/None -------------------------------------------------------------------------------- /raiden/None.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/None.lock -------------------------------------------------------------------------------- /raiden/__main__.py: -------------------------------------------------------------------------------- 1 | # make it possible to run raiden with 'python -m raiden' 2 | 3 | 4 | def main(): 5 | import gevent.monkey 6 | 7 | gevent.monkey.patch_all() 8 | from raiden.ui.cli import run 9 | 10 | # auto_envvar_prefix on a @click.command will cause all options to be 11 | # available also through environment variables prefixed with given prefix 12 | # http://click.pocoo.org/6/options/#values-from-environment-variables 13 | run(auto_envvar_prefix="RAIDEN") # pylint: disable=no-value-for-parameter 14 | 15 | 16 | if __name__ == "__main__": 17 | main() 18 | -------------------------------------------------------------------------------- /raiden/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/api/__init__.py -------------------------------------------------------------------------------- /raiden/api/objects.py: -------------------------------------------------------------------------------- 1 | class FlatList(list): 2 | """ 3 | This class inherits from list and has the same interface as a list-type. 4 | However, there is a 'data'-attribute introduced, that is required for the encoding of the list! 5 | The fields of the encoding-Schema must match the fields of the Object to be encoded! 6 | """ 7 | 8 | @property 9 | def data(self): 10 | return list(self) 11 | 12 | def __repr__(self): 13 | return "<{}: {}>".format(self.__class__.__name__, list(self)) 14 | 15 | 16 | class AddressList(FlatList): 17 | pass 18 | 19 | 20 | class PartnersPerTokenList(FlatList): 21 | pass 22 | 23 | 24 | class Address: 25 | def __init__(self, token_address): 26 | self.address = token_address 27 | 28 | 29 | class PartnersPerToken: 30 | def __init__(self, partner_address, channel): 31 | self.partner_address = partner_address 32 | self.channel = channel 33 | 34 | 35 | class DashboardGraphItem: 36 | def __init__(self, event_type_code, event_type_class_name, event_type_label, quantity, log_time, month_of_year_code, 37 | month_of_year_label): 38 | self.event_type_code = event_type_code 39 | self.event_type_class_name = event_type_class_name 40 | self.event_type_label = event_type_label 41 | self.quantity = quantity 42 | self.log_time = log_time 43 | self.month_of_year_code = month_of_year_code 44 | self.month_of_year_label = month_of_year_label 45 | 46 | 47 | class DashboardTableItem: 48 | identifier = 0 49 | log_time = "" 50 | amount = 0 51 | initiator = "" 52 | target = "" 53 | 54 | 55 | class DashboardGeneralItem: 56 | quantity = 0 57 | event_type_code = 0 58 | event_type_class_name = "" 59 | -------------------------------------------------------------------------------- /raiden/api/v1/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/api/v1/__init__.py -------------------------------------------------------------------------------- /raiden/api/validations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/api/validations/__init__.py -------------------------------------------------------------------------------- /raiden/api/validations/api_error_builder.py: -------------------------------------------------------------------------------- 1 | from flask import make_response 2 | from raiden.api.validations.api_status_codes import ERROR_STATUS_CODES 3 | import json 4 | 5 | 6 | class ApiErrorBuilder: 7 | @staticmethod 8 | def build_and_log_error(errors, status_code, log): 9 | assert status_code in ERROR_STATUS_CODES, "Programming error, unexpected error status code" 10 | if log: 11 | log.error("Error processing request", errors=errors, status_code=status_code) 12 | response = make_response( 13 | ( 14 | json.dumps(dict(errors=errors)), 15 | status_code, 16 | {"mimetype": "application/json", "Content-Type": "application/json"}, 17 | ) 18 | ) 19 | return response 20 | 21 | -------------------------------------------------------------------------------- /raiden/api/validations/api_status_codes.py: -------------------------------------------------------------------------------- 1 | from http import HTTPStatus 2 | 3 | ERROR_STATUS_CODES = [ 4 | HTTPStatus.CONFLICT, 5 | HTTPStatus.REQUEST_TIMEOUT, 6 | HTTPStatus.PAYMENT_REQUIRED, 7 | HTTPStatus.BAD_REQUEST, 8 | HTTPStatus.NOT_FOUND, 9 | HTTPStatus.NOT_IMPLEMENTED, 10 | HTTPStatus.INTERNAL_SERVER_ERROR, 11 | HTTPStatus.FORBIDDEN 12 | ] -------------------------------------------------------------------------------- /raiden/api/validations/validation_result.py: -------------------------------------------------------------------------------- 1 | from typing import NamedTuple, Any 2 | 3 | from raiden.network.proxies import Token 4 | 5 | 6 | class TokenExists(NamedTuple): 7 | error: Any = None 8 | valid: bool = False 9 | token: Token = None 10 | 11 | 12 | class EnoughBalance(NamedTuple): 13 | error: Any = None 14 | valid: bool = False 15 | balance: int = 0 16 | 17 | 18 | class EnoughGas(NamedTuple): 19 | error: Any = None 20 | valid: bool = False 21 | gas_reserve: int = 0 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /raiden/api/webui/static/endpointConfig.js: -------------------------------------------------------------------------------- 1 | const backendUrl='http://localhost:5000'; 2 | const nodeAddress = '0x01c16BF77c7d3651A5840A044A9D751655089Ac6'; 3 | const rnsDomain = null 4 | const chainEndpoint = 'http://127.0.0.1:4444'; 5 | 6 | window.luminoUrl = backendUrl; 7 | window.nodeAddress= nodeAddress; 8 | window.rnsDomain = rnsDomain; 9 | window.chainEndpoint = chainEndpoint; 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /raiden/api/webui/static/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/api/webui/static/icon.ico -------------------------------------------------------------------------------- /raiden/api/webui/static/js/runtime~main.a8a9905a.js: -------------------------------------------------------------------------------- 1 | !function(e){function r(r){for(var n,f,i=r[0],l=r[1],a=r[2],c=0,s=[];c value or self.maximum < value: 17 | msg = ("{} is outside the valide range [{},{}]").format( 18 | value, self.minimum, self.maximum 19 | ) 20 | raise ValueError(msg) 21 | 22 | @staticmethod 23 | def encode(value: int, length: int): 24 | return value.to_bytes(length, byteorder="big") 25 | 26 | @staticmethod 27 | def decode(value: bytes): 28 | return int.from_bytes(value, byteorder="big") # pylint: disable=no-member 29 | -------------------------------------------------------------------------------- /raiden/lightclient/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/lightclient/__init__.py -------------------------------------------------------------------------------- /raiden/lightclient/client_model.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | 3 | from eth_utils.typing import ChecksumAddress 4 | 5 | 6 | class ClientType(Enum): 7 | HUB = "HUB" 8 | FULL = "FULL" 9 | LIGHT = "LIGHT" 10 | 11 | 12 | class ClientModel: 13 | def __init__(self, address: ChecksumAddress, password: str, api_key: str, client_type: ClientType): 14 | self.address = address 15 | self.password = password 16 | self.api_key = api_key 17 | self.type = client_type 18 | 19 | 20 | -------------------------------------------------------------------------------- /raiden/lightclient/light_client_utils.py: -------------------------------------------------------------------------------- 1 | from raiden.storage.wal import WriteAheadLog 2 | from raiden.transfer.mediated_transfer.initiator import get_initial_lock_expiration 3 | from raiden.transfer.state import ChainState, NettingChannelState, message_identifier_from_prng 4 | from raiden.utils import random_secret, sha3, create_default_identifier 5 | from raiden.utils.typing import MessageID, PaymentID, SecretHash 6 | 7 | 8 | class LockedTransferAutogeneratedValues: 9 | def __init__(self, chain_state: ChainState, channel_state: NettingChannelState): 10 | self.secret = random_secret() 11 | self.secrethash = SecretHash(sha3(self.secret)) 12 | self.lock_expiration = get_initial_lock_expiration(chain_state.block_number, channel_state.reveal_timeout) 13 | self.payment_identifier = PaymentID(create_default_identifier()) 14 | self.message_identifier = MessageID(message_identifier_from_prng(chain_state.pseudo_random_generator)) 15 | 16 | 17 | class LightClientUtils: 18 | 19 | @classmethod 20 | def build_lt_autogen_values(cls, chain_state: ChainState, 21 | channel_state: NettingChannelState) -> LockedTransferAutogeneratedValues: 22 | return LockedTransferAutogeneratedValues(chain_state, channel_state) 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /raiden/lightclient/lightclientmessages/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/lightclient/lightclientmessages/__init__.py -------------------------------------------------------------------------------- /raiden/lightclient/lightclientmessages/hub_message.py: -------------------------------------------------------------------------------- 1 | from typing import Dict, Any 2 | from raiden.messages import Message 3 | 4 | 5 | class HubMessage: 6 | """ Representation of response to a LC request """ 7 | 8 | def __init__( 9 | self, 10 | message_id: int, 11 | message_order: int, 12 | message: Message 13 | ): 14 | self.message_id = message_id 15 | self.message_order = message_order 16 | self.message = message 17 | 18 | def to_dict(self) -> Dict[str, Any]: 19 | 20 | result_dict = { 21 | "message_id": self.message_id, 22 | "message_order" : self.message_order, 23 | "message": self.message.to_dict() 24 | 25 | } 26 | 27 | return result_dict 28 | -------------------------------------------------------------------------------- /raiden/lightclient/lightclientmessages/light_client_payment.py: -------------------------------------------------------------------------------- 1 | import string 2 | from enum import Enum 3 | from eth_utils import to_checksum_address 4 | 5 | from raiden.utils.typing import AddressHex, TokenNetworkID, Secret 6 | 7 | 8 | class LightClientPaymentStatus(Enum): 9 | InProgress = "InProgress" 10 | Expired = "Expired" 11 | Failed = "Failed" 12 | Done = "Done" 13 | Pending = "Pending" 14 | Deleted = "Deleted" 15 | 16 | 17 | class LightClientPayment: 18 | """ Representation of light client message send or received. """ 19 | 20 | def __init__( 21 | self, 22 | light_client_address: AddressHex, 23 | partner_address: AddressHex, 24 | is_lc_initiator: int, 25 | token_network_id: TokenNetworkID, 26 | amount: int, 27 | created_on: string, 28 | payment_status: LightClientPaymentStatus, 29 | identifier: string 30 | 31 | ): 32 | self.payment_id = int(identifier) 33 | self.light_client_address = to_checksum_address(light_client_address) 34 | self.partner_address = to_checksum_address(partner_address) 35 | self.is_lc_initiator = is_lc_initiator 36 | self.token_network_id = to_checksum_address(token_network_id) 37 | self.amount = amount 38 | self.created_on = created_on 39 | self.payment_status = payment_status 40 | 41 | 42 | -------------------------------------------------------------------------------- /raiden/network/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/network/__init__.py -------------------------------------------------------------------------------- /raiden/network/proxies/README.md: -------------------------------------------------------------------------------- 1 | Coding standard for this module: 2 | 3 | - Be sure to reflect changes to this module in the test 4 | implementations. [tests/utils/*_client.py] 5 | - Expose a synchronous interface by default 6 | - poll for the transaction hash 7 | - check if the proper events were emited 8 | - use `call` and `transact` to interact with client proxies 9 | - Check errors: 10 | - `call` returns the empty string if the target smart contract does not exist 11 | or the call fails, handle it accordingly (there is no way to distinguish a 12 | function that returns the empty string from the error) 13 | - the code may fail with a `require` or `revert`, for this instance the 14 | receipt will contain the status of the transaction. 15 | - the code may fail with an assert, this will spend all gas (there is no way 16 | to distinguish a transaction that used exactly all the available gas). 17 | -------------------------------------------------------------------------------- /raiden/network/proxies/__init__.py: -------------------------------------------------------------------------------- 1 | from raiden.network.proxies.discovery import Discovery # NOQA 2 | from raiden.network.proxies.token import Token # NOQA 3 | from raiden.network.proxies.token_network_registry import TokenNetworkRegistry # NOQA 4 | from raiden.network.proxies.token_network import TokenNetwork # NOQA 5 | from raiden.network.proxies.secret_registry import SecretRegistry # NOQA 6 | from raiden.network.proxies.payment_channel import PaymentChannel # NOQA 7 | -------------------------------------------------------------------------------- /raiden/network/resolver/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/network/resolver/__init__.py -------------------------------------------------------------------------------- /raiden/network/rpc/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/network/rpc/__init__.py -------------------------------------------------------------------------------- /raiden/network/rpc/transactions.py: -------------------------------------------------------------------------------- 1 | from raiden.constants import RECEIPT_FAILURE_CODE 2 | 3 | 4 | def check_transaction_threw(client, transaction_hash: bytes): 5 | """Check if the transaction threw/reverted or if it executed properly 6 | Returns None in case of success and the transaction receipt if the 7 | transaction's status indicator is 0x0. 8 | """ 9 | receipt = client.get_transaction_receipt(transaction_hash) 10 | 11 | if "status" not in receipt: 12 | raise ValueError( 13 | "Transaction receipt does not contain a status field. Upgrade your client" 14 | ) 15 | 16 | if receipt["status"] == RECEIPT_FAILURE_CODE: 17 | return receipt 18 | 19 | return None 20 | -------------------------------------------------------------------------------- /raiden/network/stunsock.py: -------------------------------------------------------------------------------- 1 | import structlog as structlog 2 | import stun 3 | 4 | from raiden.exceptions import STUNUnavailableException 5 | 6 | log = structlog.get_logger(__name__) 7 | 8 | 9 | def stun_socket(socket, source_ip="0.0.0.0", source_port=4200, stun_host=None, stun_port=3478): 10 | timeout = socket.gettimeout() 11 | socket.settimeout(2) 12 | log.debug("Initiating STUN", source_ip=source_ip, source_port=source_port) 13 | nat_type, nat = stun.get_nat_type( 14 | socket, source_ip, source_port, stun_host=stun_host, stun_port=stun_port 15 | ) 16 | external_ip = nat["ExternalIP"] 17 | if isinstance(external_ip, tuple): 18 | external_ip = external_ip[0] 19 | if external_ip is None: 20 | log.warning("STUN failed", nat=nat) 21 | raise STUNUnavailableException() 22 | external_port = nat["ExternalPort"] 23 | log.debug( 24 | "STUN-socket ready:", 25 | external_ip=external_ip, 26 | external_port=external_port, 27 | nat_type=nat_type, 28 | nat=nat, 29 | internal_ip=socket.getsockname()[0], 30 | internal_port=socket.getsockname()[1], 31 | ) 32 | nat["type"] = nat_type 33 | socket.settimeout(timeout) 34 | return external_ip, external_port, nat 35 | -------------------------------------------------------------------------------- /raiden/network/throttle.py: -------------------------------------------------------------------------------- 1 | """ 2 | This module contains the classes responsible to implement the network 3 | communication. 4 | """ 5 | from time import time 6 | 7 | 8 | class DummyPolicy: 9 | """Dummy implementation for the throttling policy that always 10 | returns a wait_time of 0. 11 | """ 12 | 13 | def __init__(self): 14 | pass 15 | 16 | def consume(self, tokens): # pylint: disable=unused-argument,no-self-use 17 | return 0.0 18 | 19 | 20 | class TokenBucket: 21 | """Implementation of the token bucket throttling algorithm. 22 | """ 23 | 24 | def __init__(self, capacity=10.0, fill_rate=10.0, time_function=None): 25 | self.capacity = float(capacity) 26 | self.fill_rate = fill_rate 27 | self.tokens = float(capacity) 28 | 29 | self._time = time_function or time 30 | self.timestamp = self._time() 31 | 32 | def consume(self, tokens): 33 | """Consume tokens. 34 | Args: 35 | tokens (float): number of transport tokens to consume 36 | Returns: 37 | wait_time (float): waiting time for the consumer 38 | """ 39 | wait_time = 0.0 40 | self.tokens -= tokens 41 | if self.tokens < 0: 42 | self._get_tokens() 43 | if self.tokens < 0: 44 | wait_time = -self.tokens / self.fill_rate 45 | return wait_time 46 | 47 | def _get_tokens(self): 48 | now = self._time() 49 | self.tokens += self.fill_rate * (now - self.timestamp) 50 | if self.tokens > self.capacity: 51 | self.tokens = self.capacity 52 | self.timestamp = now 53 | -------------------------------------------------------------------------------- /raiden/network/transport/__init__.py: -------------------------------------------------------------------------------- 1 | from raiden.network.transport.matrix import MatrixTransport # NOQA 2 | from raiden.network.transport.udp import UDPTransport # NOQA 3 | 4 | -------------------------------------------------------------------------------- /raiden/network/transport/matrix/__init__.py: -------------------------------------------------------------------------------- 1 | from raiden.network.transport.matrix.transport import MatrixTransport, _RetryQueue, MatrixLightClientTransport, NodeTransport # noqa 2 | from raiden.network.transport.matrix.utils import ( # noqa 3 | AddressReachability, 4 | UserPresence, 5 | join_global_room, 6 | login_or_register, 7 | make_client, 8 | make_room_alias, 9 | sort_servers_closest, 10 | validate_userid_signature, 11 | ) 12 | -------------------------------------------------------------------------------- /raiden/network/transport/udp/__init__.py: -------------------------------------------------------------------------------- 1 | from raiden.network.transport.udp.udp_transport import UDPTransport # NOQA 2 | -------------------------------------------------------------------------------- /raiden/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/py.typed -------------------------------------------------------------------------------- /raiden/schedulers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/schedulers/__init__.py -------------------------------------------------------------------------------- /raiden/schedulers/alive_schedule.py: -------------------------------------------------------------------------------- 1 | import requests 2 | from datetime import datetime 3 | import json 4 | import structlog 5 | from raiden.transfer import views 6 | 7 | log = structlog.get_logger(__name__) 8 | 9 | 10 | def notice_explorer_to_be_alive(endpoint_explorer, discoverable, node_address, raiden_instance): 11 | """ 12 | Notice api explorer what node is alive, sending a 13 | HTTP request 14 | """ 15 | try: 16 | 17 | raiden = raiden_instance 18 | channels = views.list_all_channelstate(chain_state=views.state_from_raiden(raiden)) 19 | 20 | if discoverable and len(channels) == 0 and endpoint_explorer: 21 | 22 | url = endpoint_explorer + "luminoNode/" + node_address 23 | 24 | response = requests.get(url) 25 | 26 | if response.status_code == 200: 27 | json_data = json.loads(response.text) 28 | data = json_data['data'] 29 | data['last_alive_signal'] = datetime.utcnow().isoformat() 30 | 31 | headers = {'Content-type': 'application/json', 'Accept': 'application/json'} 32 | 33 | response = requests.put(url, json=data, headers=headers) 34 | 35 | if response.status_code == 200: 36 | log.info("Succesfully send alive signal to Lumino Explorer") 37 | else: 38 | log.info("Warning: There was an error sending alive signal to Lumino Explorer. Status: " + 39 | str(response.status_code)) 40 | else: 41 | log.info("Warning: send alive signal to Lumino Explorer, is not posible because node is not registered") 42 | 43 | except requests.exceptions.RequestException as e: 44 | log.info("Warning: Could not connect to Lumino Explorer. Your node will not send alive signal.") 45 | 46 | -------------------------------------------------------------------------------- /raiden/schedulers/setup.py: -------------------------------------------------------------------------------- 1 | from apscheduler.schedulers.gevent import GeventScheduler 2 | from raiden.schedulers.alive_schedule import notice_explorer_to_be_alive 3 | 4 | 5 | def setup_schedule_config(self, endpoint_explorer, discoverable, node_address, raiden_instance): 6 | scheduler = GeventScheduler() 7 | scheduler.add_job(lambda : notice_explorer_to_be_alive(endpoint_explorer, discoverable, node_address, raiden_instance), 'interval', minutes=30) 8 | scheduler.start() 9 | -------------------------------------------------------------------------------- /raiden/storage/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/storage/__init__.py -------------------------------------------------------------------------------- /raiden/storage/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/storage/migrations/__init__.py -------------------------------------------------------------------------------- /raiden/storage/restore.py: -------------------------------------------------------------------------------- 1 | from raiden.exceptions import RaidenUnrecoverableError 2 | from raiden.storage.wal import restore_to_state_change 3 | from raiden.transfer import node, views 4 | from raiden.transfer.identifiers import CanonicalIdentifier 5 | from raiden.transfer.state import NettingChannelState 6 | from raiden.utils import typing 7 | 8 | 9 | def channel_state_until_state_change( 10 | raiden, canonical_identifier: CanonicalIdentifier, state_change_identifier: int 11 | ) -> typing.Optional[NettingChannelState]: 12 | """ Go through WAL state changes until a certain balance hash is found. """ 13 | wal = restore_to_state_change( 14 | transition_function=node.state_transition, 15 | storage=raiden.wal.storage, 16 | state_change_identifier=state_change_identifier, 17 | ) 18 | 19 | msg = "There is a state change, therefore the state must not be None" 20 | assert wal.state_manager.current_state is not None, msg 21 | 22 | chain_state = wal.state_manager.current_state 23 | channel_state = views.get_channelstate_by_canonical_identifier( 24 | chain_state=chain_state, canonical_identifier=canonical_identifier 25 | ) 26 | 27 | if not channel_state: 28 | raise RaidenUnrecoverableError( 29 | f"Channel was not found before state_change {state_change_identifier}" 30 | ) 31 | 32 | return channel_state 33 | -------------------------------------------------------------------------------- /raiden/storage/versions.py: -------------------------------------------------------------------------------- 1 | import os.path 2 | import re 3 | 4 | from raiden.utils.typing import List, Optional 5 | 6 | VERSION_RE = re.compile(r"^v(\d+)_log[.]db$") 7 | 8 | 9 | def latest_db_file(paths: List[str]) -> Optional[str]: 10 | """Returns the path with the highest `version` number. 11 | 12 | Raises: 13 | AssertionError: If any of the `paths` in the list is an invalid name. 14 | 15 | Args: 16 | paths: A list of file names. 17 | """ 18 | dbs = {} 19 | for db_path in paths: 20 | matches = VERSION_RE.match(os.path.basename(db_path)) 21 | assert matches, f"Invalid path name {db_path}" 22 | 23 | try: 24 | version = int(matches.group(1)) 25 | except ValueError: 26 | continue 27 | 28 | dbs[version] = db_path 29 | 30 | if dbs: 31 | highest_version = sorted(dbs)[-1] 32 | return dbs[highest_version] 33 | 34 | return None 35 | 36 | 37 | def filter_db_names(paths: List[str]) -> List[str]: 38 | """Returns a filtered list of `paths`, where every name matches our format. 39 | 40 | Args: 41 | paths: A list of file names. 42 | """ 43 | return [db_path for db_path in paths if VERSION_RE.match(os.path.basename(db_path))] 44 | -------------------------------------------------------------------------------- /raiden/test.txt: -------------------------------------------------------------------------------- 1 | const backendUrl='http://localhost:5001'const nodeAdddress = '0x4E7eA0919a88f9103e6eE5323D24A1073d79fb0D';const rnsDomain = 'marcos.rsk.co'; 2 | window.addEventListener('load', () => { 3 | window.luminoUrl = backendUrl; 4 | window.nodeAdddress= nodeAdddress; 5 | window.rnsDomain = rnsDomain 6 | }); 7 | 8 | 9 | -------------------------------------------------------------------------------- /raiden/tests/README.rst: -------------------------------------------------------------------------------- 1 | Running integration tests with different transport protocols 2 | ============================================================ 3 | 4 | Raiden can be run with two different underlying transport protocols, UDP and Matrix. Therefore tests that depend on the transport layer (all of them are integration tests) come in two versions. 5 | 6 | The pytest option ``--transport=none|udp|matrix|all`` can be used to specify which versions of the test to run. By default, only the UDP versions of the tests are run, since the Matrix versions require the local installation of the `Synapse `_ Matrix server. 7 | -------------------------------------------------------------------------------- /raiden/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/tests/__init__.py -------------------------------------------------------------------------------- /raiden/tests/benchmark/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/tests/benchmark/__init__.py -------------------------------------------------------------------------------- /raiden/tests/benchmark/utils.py: -------------------------------------------------------------------------------- 1 | def print_serialization(pstats): # pylint: disable=too-many-locals 2 | print("ncalls tottime percall % cumtime percall function") 3 | total_pct = 0.0 4 | 5 | for path_line_func, data in pstats.sort_stats("module", "cumulative").stats.items(): 6 | path, line, func = path_line_func # pylint: disable=unused-variable 7 | 8 | is_rlp = "rlp" in path 9 | is_encoding = "encoding" in path 10 | if is_rlp or is_encoding: 11 | # primitive calls dont count recursion 12 | # total calls count recursion 13 | # total time is the time for the function itself (excluding subcalls) 14 | # accumulated_time is the time of the function plus the subcalls 15 | primitive_calls, total_calls, total_time, acc_time, _ = data 16 | 17 | if primitive_calls != total_calls: 18 | calls = "{}/{}".format(total_calls, primitive_calls) 19 | else: 20 | calls = str(primitive_calls) 21 | 22 | pct = (total_time / pstats.total_tt) * 100 23 | total_pct += pct 24 | print( 25 | "{:<14} {:<8.3f} {:<8.3f} {:<3.2f} {:<8.3f} {:<8.3f} {}".format( 26 | calls, 27 | total_time, 28 | total_time / total_calls, 29 | pct, 30 | acc_time, 31 | acc_time / total_calls, 32 | func, 33 | ) 34 | ) 35 | 36 | print(" Runtime: {}, Total %: {}".format(pstats.total_tt, total_pct)) 37 | 38 | 39 | def print_slow_path(pstats): 40 | pstats.strip_dirs().sort_stats("cumulative").print_stats(15) 41 | 42 | 43 | def print_slow_function(pstats): 44 | pstats.strip_dirs().sort_stats("time").print_stats(15) 45 | -------------------------------------------------------------------------------- /raiden/tests/fixtures/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/tests/fixtures/__init__.py -------------------------------------------------------------------------------- /raiden/tests/fixtures/constants.py: -------------------------------------------------------------------------------- 1 | from eth_utils import denoms 2 | 3 | DEFAULT_PASSPHRASE = "notsosecret" # Geth's account passphrase 4 | 5 | DEFAULT_BALANCE = denoms.ether * 10 # pylint: disable=no-member 6 | DEFAULT_BALANCE_BIN = str(DEFAULT_BALANCE) 7 | -------------------------------------------------------------------------------- /raiden/tests/fuzz/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | 4 | @pytest.fixture(autouse=True) 5 | def override_capture_setting_for_hypothesis_tests(request): 6 | """override the general setting to see failed paths generated by Hypothesis """ 7 | request.config.option.showcapture = "all" 8 | -------------------------------------------------------------------------------- /raiden/tests/integration/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/tests/integration/__init__.py -------------------------------------------------------------------------------- /raiden/tests/integration/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/tests/integration/api/__init__.py -------------------------------------------------------------------------------- /raiden/tests/integration/api/conftest.py: -------------------------------------------------------------------------------- 1 | from raiden.tests.integration.api.fixtures import * # noqa: F401,F403 2 | -------------------------------------------------------------------------------- /raiden/tests/integration/api/fixtures.py: -------------------------------------------------------------------------------- 1 | # pylint: disable=too-many-arguments,redefined-outer-name 2 | import pytest 3 | 4 | from raiden.tests.integration.api.utils import create_api_server 5 | 6 | 7 | # TODO: Figure out why this fixture can't work as session scoped 8 | # What happens is that after one test is done, in the next one 9 | # the server is no longer running even though the teardown has not 10 | # been invoked. 11 | @pytest.fixture 12 | def api_server_test_instance(raiden_network, rest_api_port_number): 13 | api_server = create_api_server(raiden_network[0], rest_api_port_number) 14 | 15 | yield api_server 16 | 17 | if api_server: 18 | api_server.stop() 19 | -------------------------------------------------------------------------------- /raiden/tests/integration/api/utils.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | import gevent 4 | import psutil 5 | 6 | from raiden.api.python import RaidenAPI 7 | from raiden.api.rest import APIServer, RestAPI 8 | from raiden.app import App 9 | 10 | 11 | def wait_for_listening_port( 12 | port_number: int, tries: int = 10, sleep: float = 0.1, pid: int = None 13 | ) -> None: 14 | if pid is None: 15 | pid = os.getpid() 16 | for _ in range(tries): 17 | gevent.sleep(sleep) 18 | # macoOS requires root access for the connections api to work 19 | # so get connections of the current process only 20 | connections = psutil.Process(pid).connections() 21 | for conn in connections: 22 | if conn.status == "LISTEN" and conn.laddr[1] == port_number: 23 | return 24 | 25 | raise RuntimeError("{port} is not bound".format(port=port_number)) 26 | 27 | 28 | def create_api_server(raiden_app: App, port_number: int) -> APIServer: 29 | raiden_api = RaidenAPI(raiden_app.raiden) 30 | rest_api = RestAPI(raiden_api) 31 | api_server = APIServer(rest_api, config={"host": "localhost", "port": port_number, "explorerendpoint": "localhost:8080", "discoverable": False}) 32 | api_server.flask_app.config["SERVER_NAME"] = "localhost:{}".format(port_number) 33 | api_server.start() 34 | 35 | # Fixes flaky test, were requests are done prior to the server initializing 36 | # the listening socket. 37 | # https://github.com/raiden-network/raiden/issues/389#issuecomment-305551563 38 | wait_for_listening_port(port_number) 39 | 40 | return api_server 41 | -------------------------------------------------------------------------------- /raiden/tests/integration/cli/test_cli_development.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from raiden.constants import Environment 4 | from raiden.settings import DEVELOPMENT_CONTRACT_VERSION 5 | from raiden.tests.integration.cli.util import ( 6 | expect_cli_normal_startup, 7 | expect_cli_successful_connected, 8 | expect_cli_until_account_selection, 9 | ) 10 | 11 | pytestmark = [ 12 | pytest.mark.parametrize( 13 | "cli_tests_contracts_version", [DEVELOPMENT_CONTRACT_VERSION], scope="module" 14 | ), 15 | pytest.mark.parametrize("environment_type", [Environment.DEVELOPMENT.value], scope="module"), 16 | ] 17 | 18 | 19 | #TODO adapt to lumino entry point 20 | @pytest.mark.skip 21 | @pytest.mark.timeout(45) 22 | def test_cli_full_init_dev(cli_args, raiden_spawner): 23 | child = raiden_spawner(cli_args) 24 | expect_cli_normal_startup(child, Environment.DEVELOPMENT.value) 25 | 26 | 27 | #TODO adapt to lumino entry point 28 | @pytest.mark.skip 29 | @pytest.mark.timeout(45) 30 | @pytest.mark.parametrize("removed_args", [["address"]]) 31 | def test_cli_manual_account_selection(cli_args, raiden_spawner): 32 | child = raiden_spawner(cli_args) 33 | expect_cli_until_account_selection(child) 34 | expect_cli_successful_connected(child, Environment.DEVELOPMENT.value) 35 | -------------------------------------------------------------------------------- /raiden/tests/integration/cli/util.py: -------------------------------------------------------------------------------- 1 | def expect_cli_until_acknowledgment(child): 2 | #child.expect("Welcome to RIF Lumino Payments Protocol, Version 0.1") 3 | #child.expect("Have you read and understood and do you accept the RIF Lumino Disclosure Agreement and Privacy Warning?") 4 | child.sendline("y") 5 | 6 | 7 | def expect_cli_until_account_selection(child): 8 | expect_cli_until_acknowledgment(child) 9 | child.expect("The following accounts were found in your machine:") 10 | child.expect("Select one of them by index to continue: ") 11 | child.sendline("0") 12 | 13 | 14 | def expect_cli_successful_connected(child, mode): 15 | child.expect(f"Raiden is running in {mode} mode") 16 | child.expect("You are connected") 17 | child.expect("The Lumino API RPC server is now running") 18 | 19 | 20 | def expect_cli_normal_startup(child, mode): 21 | expect_cli_until_acknowledgment(child) 22 | expect_cli_successful_connected(child, mode) 23 | -------------------------------------------------------------------------------- /raiden/tests/integration/conftest.py: -------------------------------------------------------------------------------- 1 | from raiden.tests.integration.fixtures.blockchain import * # noqa: F401,F403 2 | from raiden.tests.integration.fixtures.raiden_network import * # noqa: F401,F403 3 | from raiden.tests.integration.fixtures.smartcontracts import * # noqa: F401,F403 4 | from raiden.tests.integration.fixtures.transport import * # noqa: F401,F403 5 | -------------------------------------------------------------------------------- /raiden/tests/integration/fixtures/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/tests/integration/fixtures/__init__.py -------------------------------------------------------------------------------- /raiden/tests/integration/long_running/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/tests/integration/long_running/__init__.py -------------------------------------------------------------------------------- /raiden/tests/integration/network/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/tests/integration/network/__init__.py -------------------------------------------------------------------------------- /raiden/tests/integration/network/proxies/test_token.py: -------------------------------------------------------------------------------- 1 | from eth_utils import to_canonical_address, to_checksum_address 2 | 3 | from raiden.network.proxies.token import Token 4 | from raiden.network.rpc.client import JSONRPCClient 5 | from raiden.utils import privatekey_to_address 6 | 7 | 8 | def test_token(deploy_client, token_proxy, private_keys, web3, contract_manager): 9 | privkey = private_keys[1] 10 | address = privatekey_to_address(privkey) 11 | address = to_canonical_address(address) 12 | other_client = JSONRPCClient(web3, privkey) 13 | other_token_proxy = Token( 14 | jsonrpc_client=other_client, 15 | token_address=to_canonical_address(token_proxy.proxy.contract.address), 16 | contract_manager=contract_manager, 17 | ) 18 | 19 | # send some funds from deployer to generated address 20 | transfer_funds = 100 21 | token_proxy.transfer(address, transfer_funds) 22 | assert transfer_funds == token_proxy.balance_of(address) 23 | allow_funds = 100 24 | token_proxy.approve(address, allow_funds) 25 | assert allow_funds == token_proxy.proxy.contract.functions.allowance( 26 | to_checksum_address(deploy_client.address), to_checksum_address(address) 27 | ).call(block_identifier="latest") 28 | other_token_proxy.transfer(deploy_client.address, transfer_funds) 29 | assert token_proxy.balance_of(address) == 0 30 | -------------------------------------------------------------------------------- /raiden/tests/integration/network/transport/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/tests/integration/network/transport/__init__.py -------------------------------------------------------------------------------- /raiden/tests/integration/rpc/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/tests/integration/rpc/__init__.py -------------------------------------------------------------------------------- /raiden/tests/integration/rpc/assumptions/test_parity_rpc_assumptions.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from raiden.tests.utils.smartcontracts import deploy_rpc_test_contract 4 | from raiden.utils import safe_gas_limit 5 | 6 | pytestmark = pytest.mark.usefixtures("skip_if_not_parity") 7 | 8 | # set very low values to force the client to prune old state 9 | STATE_PRUNNING = { 10 | "pruning": "fast", 11 | "pruning-history": 1, 12 | "pruning-memory": 1, 13 | "cache-size-db": 1, 14 | "cache-size-blocks": 1, 15 | "cache-size-queue": 1, 16 | "cache-size": 1, 17 | } 18 | 19 | 20 | @pytest.mark.parametrize("blockchain_extra_config", [STATE_PRUNNING]) 21 | def test_parity_request_prunned_data_raises_an_exception(deploy_client): 22 | """ Interacting with an old block identifier with a pruning client throws. """ 23 | contract_proxy = deploy_rpc_test_contract(deploy_client, "RpcWithStorageTest") 24 | iterations = 1000 25 | 26 | def send_transaction(): 27 | check_block = deploy_client.get_checking_block() 28 | startgas = contract_proxy.estimate_gas(check_block, "waste_storage", iterations) 29 | startgas = safe_gas_limit(startgas) 30 | transaction = contract_proxy.transact("waste_storage", startgas, iterations) 31 | deploy_client.poll(transaction) 32 | return deploy_client.get_transaction_receipt(transaction) 33 | 34 | first_receipt = send_transaction() 35 | pruned_block_number = first_receipt["blockNumber"] 36 | 37 | for _ in range(10): 38 | send_transaction() 39 | 40 | with pytest.raises(ValueError): 41 | contract_proxy.contract.functions.const().call(block_identifier=pruned_block_number) 42 | 43 | with pytest.raises(ValueError): 44 | contract_proxy.contract.functions.get(1).call(block_identifier=pruned_block_number) 45 | -------------------------------------------------------------------------------- /raiden/tests/integration/rpc/test_client.py: -------------------------------------------------------------------------------- 1 | import gevent 2 | 3 | from raiden.network.rpc.client import geth_discover_next_available_nonce 4 | from raiden.tests.utils.factories import make_address 5 | 6 | 7 | def test_geth_discover_next_available_nonce( 8 | deploy_client, skip_if_parity # pylint: disable=unused-argument 9 | ): 10 | """ Test that geth_discover_next_available nonce works correctly 11 | 12 | Reproduced the problem seen here: 13 | https://github.com/raiden-network/raiden/pull/3683#issue-264551799 14 | """ 15 | 16 | greenlets = set() 17 | for _ in range(100): 18 | greenlets.add( 19 | gevent.spawn(deploy_client.send_transaction, make_address(), 50000) # to # startgas 20 | ) 21 | gevent.sleep(0.5) 22 | 23 | nonce = geth_discover_next_available_nonce( 24 | web3=deploy_client.web3, address=deploy_client.address 25 | ) 26 | assert nonce > 0 27 | assert nonce < 100 28 | 29 | gevent.joinall(greenlets, raise_error=True) 30 | -------------------------------------------------------------------------------- /raiden/tests/integration/test_blockchainservice.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from raiden.exceptions import SamePeerAddress 4 | from raiden.tests.utils.detect_failure import raise_on_failure 5 | from raiden.transfer import views 6 | 7 | 8 | @pytest.mark.parametrize("number_of_nodes", [1]) 9 | @pytest.mark.parametrize("channels_per_node", [0]) 10 | def test_channel_with_self(raiden_network, settle_timeout, token_addresses): 11 | raise_on_failure( 12 | raiden_network, 13 | run_test_channel_with_self, 14 | raiden_network=raiden_network, 15 | settle_timeout=settle_timeout, 16 | token_addresses=token_addresses, 17 | ) 18 | 19 | 20 | def run_test_channel_with_self(raiden_network, settle_timeout, token_addresses): 21 | app0, = raiden_network # pylint: disable=unbalanced-tuple-unpacking 22 | 23 | registry_address = app0.raiden.default_registry.address 24 | token_address = token_addresses[0] 25 | 26 | current_chanels = views.list_channelstate_for_tokennetwork( 27 | views.state_from_app(app0), registry_address, token_address 28 | ) 29 | assert not current_chanels 30 | 31 | token_network_address = app0.raiden.default_registry.get_token_network(token_address) 32 | token_network0 = app0.raiden.chain.token_network(token_network_address) 33 | 34 | with pytest.raises(SamePeerAddress) as excinfo: 35 | token_network0.new_netting_channel( 36 | partner=app0.raiden.address, 37 | settle_timeout=settle_timeout, 38 | given_block_identifier="latest", 39 | ) 40 | 41 | assert "The other peer must not have the same address as the client." in str(excinfo.value) 42 | -------------------------------------------------------------------------------- /raiden/tests/integration/transfer/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/tests/integration/transfer/__init__.py -------------------------------------------------------------------------------- /raiden/tests/scenarios/ms1_simple_monitoring.yaml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | settings: 4 | gas_price: "fast" 5 | # Adapt to chain used 6 | chain: any 7 | services: 8 | udc: 9 | enable: true 10 | token: 11 | deposit: true 12 | token: 13 | 14 | nodes: 15 | mode: managed 16 | count: 2 17 | 18 | default_options: 19 | gas-price: fast 20 | environment-type: development 21 | enable-monitoring: true 22 | 23 | # This is the MS1 scenario. A channel between two nodes is opened, a transfer is made. Then, node 1 goes offline 24 | # and node 0 closes the channel. The last assert checks whether the monitoring service interferes and received its reward 25 | 26 | scenario: 27 | serial: 28 | tasks: 29 | - open_channel: {from: 0, to: 1, total_deposit: 1000} 30 | - transfer: {from: 0, to: 1, amount: 500, expected_http_status: 200} 31 | ## Wait for Monitor Request to be sent 32 | - wait: 10 33 | - store_channel_info: {from: 0, to: 1, key: "MS Test Channel"} 34 | - stop_node: 1 35 | - close_channel: {from: 0, to: 1} 36 | ## Wait for channel to be closed 37 | - wait: 50 38 | - assert: {from: 0 ,to: 1, total_deposit: 1000, balance: 500, state: "closed"} 39 | - assert_events: {contract_name: "TokenNetwork", event_name: "ChannelClosed", num_events: 1} 40 | 41 | ## Current blocktime Kovan 15s, so monitoring service reacts after 0.3 * 500 * 15 seconds 42 | - wait: 3000 43 | - assert_events: {contract_name: "TokenNetwork", event_name: "NonClosingBalanceProofUpdated", num_events: 1} 44 | 45 | ## Monitored channel must be settled before the monitoring service can claim its reward 46 | ## Settlement timeout is 500 blocks -> 500 * 15s in Kovan = 7500s 47 | - wait: 8000 48 | - assert_ms_claim: {channel_info_key: "MS Test Channel"} 49 | -------------------------------------------------------------------------------- /raiden/tests/scenarios/old_scenarios/Scenario-Kill-Receiver.yaml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | settings: 4 | gas_price: "fast" 5 | chain: any 6 | 7 | token: 8 | ##address: "0xabEE20bdA7476337ea051Dac011763F6D7eD8d9c" 9 | 10 | nodes: 11 | mode: managed 12 | count: 6 13 | default_options: 14 | gas-price: fast 15 | registry-contract-address: "0xbfa863Ac58a3E0A82B58a8e958F2752Bfb573388" 16 | discovery-contract-address: "0xb2646EB8270a4de7451f6F7b259FdE17DBCeedc9" 17 | secret-registry-contract-address: "0xA5c882f09c3DE551d76dcDE08890fAa0dD1F29E3" 18 | 19 | 20 | 21 | scenario: 22 | serial: 23 | tasks: 24 | - parallel: 25 | name: "Open channels" 26 | tasks: 27 | - open_channel: {from: 0, to: 1, total_deposit: 10, settle_timeout: 50} 28 | - open_channel: {from: 1, to: 2, total_deposit: 10, settle_timeout: 50} 29 | - open_channel: {from: 2, to: 3, total_deposit: 10, settle_timeout: 50} 30 | - open_channel: {from: 3, to: 4, total_deposit: 10, settle_timeout: 50} 31 | - open_channel: {from: 4, to: 5, total_deposit: 10, settle_timeout: 50} 32 | 33 | ## total overall deposit 120 34 | 35 | - parallel: 36 | name: "Send tokens to Node 5 and kill it " 37 | tasks: 38 | - transfer: {from: 0, to: 5, amount: 3, expected_http_status: 408} 39 | - serial: 40 | tasks: 41 | - wait: 2 42 | - kill_node: 5 43 | 44 | -------------------------------------------------------------------------------- /raiden/tests/scenarios/old_scenarios/Scenario-Re-Routing.yaml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | settings: 4 | gas_price: "fast" 5 | chain: any 6 | 7 | token: 8 | ##address: "0xabEE20bdA7476337ea051Dac011763F6D7eD8d9c" 9 | 10 | nodes: 11 | mode: managed 12 | count: 7 13 | default_options: 14 | gas-price: fast 15 | registry-contract-address: "0xbfa863Ac58a3E0A82B58a8e958F2752Bfb573388" 16 | discovery-contract-address: "0xb2646EB8270a4de7451f6F7b259FdE17DBCeedc9" 17 | secret-registry-contract-address: "0xA5c882f09c3DE551d76dcDE08890fAa0dD1F29E3" 18 | 19 | 20 | 21 | scenario: 22 | serial: 23 | tasks: 24 | - parallel: 25 | name: "Open channels" 26 | tasks: 27 | - open_channel: {from: 0, to: 1, total_deposit: 10, settle_timeout: 50} 28 | - open_channel: {from: 1, to: 2, total_deposit: 10, settle_timeout: 50} 29 | - open_channel: {from: 1, to: 3, total_deposit: 10, settle_timeout: 50} 30 | - open_channel: {from: 3, to: 4, total_deposit: 10, settle_timeout: 50} 31 | - open_channel: {from: 4, to: 5, total_deposit: 10, settle_timeout: 50} 32 | - open_channel: {from: 5, to: 6, total_deposit: 10, settle_timeout: 50} 33 | - open_channel: {from: 2, to: 6, total_deposit: 10, settle_timeout: 50} 34 | 35 | - serial: 36 | name: "Send tokens to Node 5 and kill it " 37 | tasks: 38 | - transfer: {from: 2, to: 6, amount: 10, expected_http_status: 200} 39 | - transfer: {from: 0, to: 6, amount: 3, expected_http_status: 200} ## Routing thinks the path would be over node 2 (shortest) 40 | - wait: 10 41 | - assert: {from: 1, to: 2, balance: 10, state: "opened"} ## this should stay the same, since there must be a refund transfer 42 | 43 | 44 | -------------------------------------------------------------------------------- /raiden/tests/scenarios/old_scenarios/join-network-scenario-J1.yaml: -------------------------------------------------------------------------------- 1 | settings: 2 | gas_price: "fast" 3 | 4 | token: 5 | 6 | nodes: 7 | commands: 8 | stop: "pkill -f '127.0.0.1:50{:02d}'" 9 | kill: "pkill -9 -f '127.0.0.1:50{:02d}'" 10 | start: "raiden --config-file raiden_{0:02d}.toml --api-address 127.0.0.1:50{0:02d}" 11 | range: 12 | first: 1 13 | last: 4 14 | template: "localhost:50{:02d}" 15 | 16 | scenario: 17 | serial: 18 | tasks: 19 | - parallel: 20 | name: "Setting up a network" 21 | tasks: 22 | - open_channel: {from: 0, to: 1, total_deposit: 10, expected_http_status: 201} 23 | - open_channel: {from: 0, to: 2, total_deposit: 10, expected_http_status: 201} 24 | - open_channel: {from: 1, to: 2, total_deposit: 10, expected_http_status: 201} 25 | - serial: 26 | name: "Checking the network" 27 | tasks: 28 | - assert: {from: 0, to: 1, total_deposit: 10, balance: 10, state: "opened"} 29 | - assert: {from: 0, to: 2, total_deposit: 10, balance: 10, state: "opened"} 30 | - assert: {from: 1, to: 2, total_deposit: 10, balance: 10, state: "opened"} 31 | - serial: 32 | name: "Node Nr. 4 joins" 33 | tasks: 34 | - join_network: {from: 3, funds: 100, initial_channel_target: 3, joinable_funds_target: 0.4, expected_http_status: 204} 35 | - assert: {from: 3, to: 0, total_deposit: 20, balance: 20, state: "opened"} 36 | - assert: {from: 3, to: 1, total_deposit: 20, balance: 20, state: "opened"} 37 | - assert: {from: 3, to: 2, total_deposit: 20, balance: 20, state: "opened"} 38 | -------------------------------------------------------------------------------- /raiden/tests/scenarios/old_scenarios/join-network-scenario-J11.yaml: -------------------------------------------------------------------------------- 1 | settings: 2 | gas_price: "fast" 3 | 4 | token: 5 | 6 | nodes: 7 | commands: 8 | stop: "pkill -f '127.0.0.1:50{:02d}'" 9 | kill: "pkill -9 -f '127.0.0.1:50{:02d}'" 10 | start: "raiden --config-file raiden_{0:02d}.toml --api-address 127.0.0.1:50{0:02d}" 11 | range: 12 | first: 1 13 | last: 4 14 | template: "localhost:50{:02d}" 15 | 16 | scenario: 17 | serial: 18 | tasks: 19 | - parallel: 20 | name: "Setting up a network" 21 | tasks: 22 | - open_channel: {from: 0, to: 1, total_deposit: 10, expected_http_status: 201} 23 | - open_channel: {from: 0, to: 2, total_deposit: 10, expected_http_status: 201} 24 | - open_channel: {from: 1, to: 2, total_deposit: 10, expected_http_status: 201} 25 | 26 | - serial: 27 | name: "Checking the network" 28 | tasks: 29 | - assert: {from: 0, to: 1, total_deposit: 10, balance: 10, state: "opened"} 30 | - assert: {from: 0, to: 2, total_deposit: 10, balance: 10, state: "opened"} 31 | - assert: {from: 1, to: 2, total_deposit: 10, balance: 10, state: "opened"} 32 | 33 | - serial: 34 | name: "Node Nr. 4 joins a network with 100 funds and joinable_funds_target set to 1" 35 | tasks: 36 | - join_network: {from: 3, funds: 100, joinable_funds_target: 1, expected_http_status: 204} 37 | - assert: {from: 3, to: 0, total_deposit: 0, balance: 0, state: "opened"} 38 | - assert: {from: 3, to: 1, total_deposit: 0, balance: 0, state: "opened"} 39 | - assert: {from: 3, to: 2, total_deposit: 0, balance: 0, state: "opened"} 40 | -------------------------------------------------------------------------------- /raiden/tests/scenarios/old_scenarios/join-network-scenario-J12.yaml: -------------------------------------------------------------------------------- 1 | settings: 2 | gas_price: "fast" 3 | 4 | token: 5 | 6 | nodes: 7 | commands: 8 | stop: "pkill -f '127.0.0.1:50{:02d}'" 9 | kill: "pkill -9 -f '127.0.0.1:50{:02d}'" 10 | start: "raiden --config-file raiden_{0:02d}.toml --api-address 127.0.0.1:50{0:02d}" 11 | range: 12 | first: 1 13 | last: 4 14 | template: "localhost:50{:02d}" 15 | 16 | scenario: 17 | serial: 18 | tasks: 19 | - parallel: 20 | name: "Setting up a network" 21 | tasks: 22 | - open_channel: {from: 0, to: 1, total_deposit: 10, expected_http_status: 201} 23 | - open_channel: {from: 0, to: 2, total_deposit: 10, expected_http_status: 201} 24 | - open_channel: {from: 1, to: 2, total_deposit: 10, expected_http_status: 201} 25 | 26 | - serial: 27 | name: "Checking the network" 28 | tasks: 29 | - assert: {from: 0, to: 1, total_deposit: 10, balance: 10, state: "opened"} 30 | - assert: {from: 0, to: 2, total_deposit: 10, balance: 10, state: "opened"} 31 | - assert: {from: 1, to: 2, total_deposit: 10, balance: 10, state: "opened"} 32 | 33 | - serial: 34 | name: "Node Nr. 4 joins a network with 100 funds and initial_channel_target set to 1" 35 | tasks: 36 | - join_network: {from: 3, funds: 100, initial_channel_target: 1, expected_http_status: 204} # We expect 1 channel open with 60 tokens but we do not know with whom 37 | #TODO: add assertion once partner selection is deterministic or add new assert request to check for new channels -------------------------------------------------------------------------------- /raiden/tests/scenarios/old_scenarios/join-network-scenario-J13.yaml: -------------------------------------------------------------------------------- 1 | settings: 2 | gas_price: "fast" 3 | 4 | token: 5 | 6 | nodes: 7 | commands: 8 | stop: "pkill -f '127.0.0.1:50{:02d}'" 9 | kill: "pkill -9 -f '127.0.0.1:50{:02d}'" 10 | start: "raiden --config-file raiden_{0:02d}.toml --api-address 127.0.0.1:50{0:02d}" 11 | range: 12 | first: 1 13 | last: 4 14 | template: "localhost:50{:02d}" 15 | 16 | scenario: 17 | serial: 18 | tasks: 19 | - parallel: 20 | name: "Setting up a network" 21 | tasks: 22 | - open_channel: {from: 0, to: 1, total_deposit: 10, expected_http_status: 201} 23 | - open_channel: {from: 0, to: 2, total_deposit: 10, expected_http_status: 201} 24 | - open_channel: {from: 1, to: 2, total_deposit: 10, expected_http_status: 201} 25 | 26 | - serial: 27 | name: "Checking the network" 28 | tasks: 29 | - assert: {from: 0, to: 1, total_deposit: 10, balance: 10, state: "opened"} 30 | - assert: {from: 0, to: 2, total_deposit: 10, balance: 10, state: "opened"} 31 | - assert: {from: 1, to: 2, total_deposit: 10, balance: 10, state: "opened"} 32 | 33 | - serial: 34 | name: "Node Nr. 4 joins a network with 100 funds and initial_channel_target set to 1 and joinable_funds set to 1" 35 | tasks: 36 | - join_network: {from: 3, funds: 100, initial_channel_target: 1, joinable_funds_target: 1, expected_http_status: 204} # We expect 1 channel open with 0 tokens but we do not know with whom 37 | #TODO: add assertion once partner selection is deterministic or add new assert request to check for new channels -------------------------------------------------------------------------------- /raiden/tests/scenarios/old_scenarios/join-network-scenario-J15.yaml: -------------------------------------------------------------------------------- 1 | settings: 2 | gas_price: "fast" 3 | 4 | token: 5 | 6 | nodes: 7 | commands: 8 | stop: "pkill -f '127.0.0.1:50{:02d}'" 9 | kill: "pkill -9 -f '127.0.0.1:50{:02d}'" 10 | start: "raiden --config-file raiden_{0:02d}.toml --api-address 127.0.0.1:50{0:02d}" 11 | range: 12 | first: 1 13 | last: 4 14 | template: "localhost:50{:02d}" 15 | 16 | scenario: 17 | serial: 18 | tasks: 19 | - parallel: 20 | name: "Setting up a network" 21 | tasks: 22 | - open_channel: {from: 0, to: 1, total_deposit: 10, expected_http_status: 201} 23 | - open_channel: {from: 0, to: 2, total_deposit: 10, expected_http_status: 201} 24 | - open_channel: {from: 1, to: 2, total_deposit: 10, expected_http_status: 201} 25 | 26 | - serial: 27 | name: "Checking the network" 28 | tasks: 29 | - assert: {from: 0, to: 1, total_deposit: 10, balance: 10, state: "opened"} 30 | - assert: {from: 0, to: 2, total_deposit: 10, balance: 10, state: "opened"} 31 | - assert: {from: 1, to: 2, total_deposit: 10, balance: 10, state: "opened"} 32 | 33 | - serial: 34 | name: "Node Nr. 4 joins a network with 73 funds and joinable_funds set to 1" 35 | tasks: 36 | - join_network: {from: 3, funds: 73, joinable_funds_target: 1, expected_http_status: 204} # We expect 3 channels open with 0 tokens in it 37 | - assert: {from: 3, to: 0, total_deposit: 0, balance: 0, state: "opened"} 38 | - assert: {from: 3, to: 1, total_deposit: 0, balance: 0, state: "opened"} 39 | - assert: {from: 3, to: 2, total_deposit: 0, balance: 0, state: "opened"} -------------------------------------------------------------------------------- /raiden/tests/scenarios/old_scenarios/join-network-scenario-J16.yaml: -------------------------------------------------------------------------------- 1 | settings: 2 | gas_price: "fast" 3 | 4 | token: 5 | 6 | nodes: 7 | commands: 8 | stop: "pkill -f '127.0.0.1:50{:02d}'" 9 | kill: "pkill -9 -f '127.0.0.1:50{:02d}'" 10 | start: "raiden --config-file raiden_{0:02d}.toml --api-address 127.0.0.1:50{0:02d}" 11 | range: 12 | first: 1 13 | last: 4 14 | template: "localhost:50{:02d}" 15 | 16 | scenario: 17 | serial: 18 | tasks: 19 | - parallel: 20 | name: "Setting up a network" 21 | tasks: 22 | - open_channel: {from: 0, to: 1, total_deposit: 10, expected_http_status: 201} 23 | - open_channel: {from: 0, to: 2, total_deposit: 10, expected_http_status: 201} 24 | - open_channel: {from: 1, to: 2, total_deposit: 10, expected_http_status: 201} 25 | 26 | - serial: 27 | name: "Checking the network" 28 | tasks: 29 | - assert: {from: 0, to: 1, total_deposit: 10, balance: 10, state: "opened"} 30 | - assert: {from: 0, to: 2, total_deposit: 10, balance: 10, state: "opened"} 31 | - assert: {from: 1, to: 2, total_deposit: 10, balance: 10, state: "opened"} 32 | 33 | - serial: 34 | name: "Node Nr. 4 joins a network with less than 5 tokens and default values" 35 | tasks: 36 | - join_network: {from: 3, funds: 5, expected_http_status: 204} 37 | - assert: {from: 3, to: 0, total_deposit: 1, balance: 1, state: "opened"} 38 | - assert: {from: 3, to: 1, total_deposit: 1, balance: 1, state: "opened"} 39 | - assert: {from: 3, to: 2, total_deposit: 1, balance: 1, state: "opened"} -------------------------------------------------------------------------------- /raiden/tests/scenarios/old_scenarios/join-network-scenario-J17.yaml: -------------------------------------------------------------------------------- 1 | settings: 2 | gas_price: "fast" 3 | 4 | token: 5 | 6 | nodes: 7 | commands: 8 | stop: "pkill -f '127.0.0.1:50{:02d}'" 9 | kill: "pkill -9 -f '127.0.0.1:50{:02d}'" 10 | start: "raiden --config-file raiden_{0:02d}.toml --api-address 127.0.0.1:50{0:02d}" 11 | range: 12 | first: 1 13 | last: 4 14 | template: "localhost:50{:02d}" 15 | 16 | scenario: 17 | serial: 18 | tasks: 19 | - parallel: 20 | name: "Setting up a network" 21 | tasks: 22 | - open_channel: {from: 0, to: 1, total_deposit: 10, expected_http_status: 201} 23 | - open_channel: {from: 0, to: 2, total_deposit: 10, expected_http_status: 201} 24 | - open_channel: {from: 1, to: 2, total_deposit: 10, expected_http_status: 201} 25 | 26 | - serial: 27 | name: "Checking the network" 28 | tasks: 29 | - assert: {from: 0, to: 1, total_deposit: 10, balance: 10, state: "opened"} 30 | - assert: {from: 0, to: 2, total_deposit: 10, balance: 10, state: "opened"} 31 | - assert: {from: 1, to: 2, total_deposit: 10, balance: 10, state: "opened"} 32 | 33 | - serial: 34 | name: "Node Nr. 4 joins a network with joinable_funds_target set to >1" 35 | tasks: 36 | - join_network: {from: 3, funds: 100, joinable_funds_target: 2, expected_http_status: 409} # Bug it actually opens three channel with 0 deposit and balance 37 | #TODO: write new test when bug #2676 is fixed 38 | -------------------------------------------------------------------------------- /raiden/tests/scenarios/old_scenarios/join-network-scenario-J18.yaml: -------------------------------------------------------------------------------- 1 | settings: 2 | gas_price: "fast" 3 | 4 | token: 5 | 6 | nodes: 7 | commands: 8 | stop: "pkill -f '127.0.0.1:50{:02d}'" 9 | kill: "pkill -9 -f '127.0.0.1:50{:02d}'" 10 | start: "raiden --config-file raiden_{0:02d}.toml --api-address 127.0.0.1:50{0:02d}" 11 | range: 12 | first: 1 13 | last: 5 14 | template: "localhost:50{:02d}" 15 | 16 | scenario: 17 | serial: 18 | tasks: 19 | - parallel: 20 | name: "Setting up a network" 21 | tasks: 22 | - open_channel: {from: 0, to: 1, total_deposit: 10, expected_http_status: 201} 23 | - open_channel: {from: 0, to: 2, total_deposit: 10, expected_http_status: 201} 24 | - open_channel: {from: 1, to: 2, total_deposit: 10, expected_http_status: 201} 25 | 26 | - serial: 27 | name: "Checking the network" 28 | tasks: 29 | - assert: {from: 0, to: 1, total_deposit: 10, balance: 10, state: "opened"} 30 | - assert: {from: 0, to: 2, total_deposit: 10, balance: 10, state: "opened"} 31 | - assert: {from: 1, to: 2, total_deposit: 10, balance: 10, state: "opened"} 32 | 33 | - serial: 34 | name: "Node Nr. 4 joins a network with initial_channel_target > participants in the network" 35 | tasks: 36 | - join_network: {from: 3, funds: 100, initial_channel_target: 4, expected_http_status: 204} # the forth channel should be opened after the fifth node joins 37 | - assert: {from: 3, to: 0, total_deposit: 15, balance: 15, state: "opened"} 38 | - assert: {from: 3, to: 1, total_deposit: 15, balance: 15, state: "opened"} 39 | - assert: {from: 3, to: 2, total_deposit: 15, balance: 15, state: "opened"} 40 | 41 | -------------------------------------------------------------------------------- /raiden/tests/scenarios/old_scenarios/join-network-scenario-J6.yaml: -------------------------------------------------------------------------------- 1 | settings: 2 | gas_price: "fast" 3 | 4 | token: 5 | 6 | nodes: 7 | commands: 8 | #start: "docker start raiden_{:02d}" 9 | #stop: "docker stop raiden_{:02d}" 10 | #kill: "docker kill raiden_{:02d}" 11 | stop: "pkill -f '127.0.0.1:50{:02d}'" 12 | kill: "pkill -9 -f '127.0.0.1:50{:02d}'" 13 | start: "raiden --config-file raiden_{0:02d}.toml --api-address 127.0.0.1:50{0:02d}" 14 | range: 15 | first: 1 16 | last: 5 17 | template: "localhost:50{:02d}" 18 | 19 | scenario: 20 | serial: 21 | tasks: 22 | - parallel: 23 | name: "Setting up a network" 24 | tasks: 25 | - open_channel: {from: 0, to: 1, total_deposit: 10, expected_http_status: 201} 26 | - open_channel: {from: 0, to: 2, total_deposit: 10, expected_http_status: 201} 27 | - open_channel: {from: 1, to: 2, total_deposit: 10, expected_http_status: 201} 28 | 29 | - serial: 30 | name: "Checking the network" 31 | tasks: 32 | - assert: {from: 0, to: 1, total_deposit: 10, balance: 10, state: "opened"} 33 | - assert: {from: 0, to: 2, total_deposit: 10, balance: 10, state: "opened"} 34 | - assert: {from: 1, to: 2, total_deposit: 10, balance: 10, state: "opened"} 35 | 36 | - serial: 37 | name: "Node Nr. 4 joins with 0 funds and default additional arguments" 38 | tasks: 39 | - join_network: {from: 3, funds: 0, expected_http_status: 409} -------------------------------------------------------------------------------- /raiden/tests/scenarios/old_scenarios/join-network-scenario-J8.yaml: -------------------------------------------------------------------------------- 1 | settings: 2 | gas_price: "fast" 3 | 4 | token: 5 | 6 | nodes: 7 | commands: 8 | stop: "pkill -f '127.0.0.1:50{:02d}'" 9 | kill: "pkill -9 -f '127.0.0.1:50{:02d}'" 10 | start: "raiden --config-file raiden_{0:02d}.toml --api-address 127.0.0.1:50{0:02d}" 11 | range: 12 | first: 1 13 | last: 4 14 | template: "localhost:50{:02d}" 15 | 16 | 17 | scenario: 18 | serial: 19 | tasks: 20 | - parallel: 21 | name: "Setting up a network" 22 | tasks: 23 | - open_channel: {from: 0, to: 1, total_deposit: 10, expected_http_status: 201} 24 | - open_channel: {from: 0, to: 2, total_deposit: 10, expected_http_status: 201} 25 | - open_channel: {from: 1, to: 2, total_deposit: 10, expected_http_status: 201} 26 | 27 | - serial: 28 | name: "Checking the network" 29 | tasks: 30 | - assert: {from: 0, to: 1, total_deposit: 10, balance: 10, state: "opened"} 31 | - assert: {from: 0, to: 2, total_deposit: 10, balance: 10, state: "opened"} 32 | - assert: {from: 1, to: 2, total_deposit: 10, balance: 10, state: "opened"} 33 | 34 | - serial: 35 | name: "Node Nr. 4 joins with initial_channel_target set to 0" 36 | tasks: 37 | - join_network: {from: 3, funds: 100, initial_channel_target: 0, expected_http_status: 204} # It opens with default values 38 | - assert: {from: 3, to: 0, total_deposit: 20, balance: 20, state: "opened"} 39 | - assert: {from: 3, to: 1, total_deposit: 20, balance: 20, state: "opened"} 40 | - assert: {from: 3, to: 2, total_deposit: 20, balance: 20, state: "opened"} 41 | #TODO: write new test when bug #2675 is fixed 42 | -------------------------------------------------------------------------------- /raiden/tests/scenarios/old_scenarios/join-network-scenario-J9.yaml: -------------------------------------------------------------------------------- 1 | settings: 2 | gas_price: "fast" 3 | 4 | token: 5 | 6 | nodes: 7 | commands: 8 | stop: "pkill -f '127.0.0.1:50{:02d}'" 9 | kill: "pkill -9 -f '127.0.0.1:50{:02d}'" 10 | start: "raiden --config-file raiden_{0:02d}.toml --api-address 127.0.0.1:50{0:02d}" 11 | range: 12 | first: 1 13 | last: 4 14 | template: "localhost:50{:02d}" 15 | 16 | scenario: 17 | serial: 18 | tasks: 19 | - parallel: 20 | name: "Setting up a network" 21 | tasks: 22 | - open_channel: {from: 0, to: 1, total_deposit: 10, expected_http_status: 201} 23 | - open_channel: {from: 0, to: 2, total_deposit: 10, expected_http_status: 201} 24 | - open_channel: {from: 1, to: 2, total_deposit: 10, expected_http_status: 201} 25 | 26 | - serial: 27 | name: "Checking the network" 28 | tasks: 29 | - assert: {from: 0, to: 1, total_deposit: 10, balance: 10, state: "opened"} 30 | - assert: {from: 0, to: 2, total_deposit: 10, balance: 10, state: "opened"} 31 | - assert: {from: 1, to: 2, total_deposit: 10, balance: 10, state: "opened"} 32 | 33 | - serial: 34 | name: "Node Nr. 4 joins with a prime number funds and default arguments" 35 | tasks: 36 | - join_network: {from: 3, funds: 97, expected_http_status: 204} #it gets rounded as expected 19 each, since 0.6 * 97 / 3 = 19.4 37 | - assert: {from: 3, to: 0, total_deposit: 19, balance: 19, state: "opened"} 38 | - assert: {from: 3, to: 1, total_deposit: 19, balance: 19, state: "opened"} 39 | - assert: {from: 3, to: 2, total_deposit: 19, balance: 19, state: "opened"} 40 | -------------------------------------------------------------------------------- /raiden/tests/scenarios/old_scenarios/leave-network-on-closed_channels.yaml: -------------------------------------------------------------------------------- 1 | settings: 2 | gas_price: "fast" 3 | 4 | nodes: 5 | commands: 6 | #start: "docker start raiden_{:02d}" 7 | #stop: "docker stop raiden_{:02d}" 8 | #kill: "docker kill raiden_{:02d}" 9 | stop: "pkill -f '127.0.0.1:50{:02d}'" 10 | kill: "pkill -9 -f '127.0.0.1:50{:02d}'" 11 | start: "raiden --config-file raiden_{0:02d}.toml --api-address 127.0.0.1:50{0:02d}" 12 | range: 13 | first: 1 14 | last: 3 15 | template: "localhost:50{:02d}" 16 | 17 | # Open and close all channels, and check that leaving the network succeeds 18 | scenario: 19 | serial: 20 | tasks: 21 | - parallel: 22 | tasks: 23 | # Open Channels 24 | - open_channel: {from: 2, to: 0, total_deposit: 10} 25 | - open_channel: {from: 2, to: 1, total_deposit: 10} 26 | - open_channel: {from: 0, to: 1, total_deposit: 10} 27 | - parallel: 28 | tasks: 29 | - close_channel: {from: 2, to: 0} 30 | - close_channel: {from: 2, to: 1} 31 | - close_channel: {from: 0, to: 1} 32 | - parallel: 33 | tasks: 34 | # Check that the channels with node 2 are closed 35 | - assert: {from: 2, to: 0, expected_http_status: 200, state: "closed"} 36 | - assert: {from: 2, to: 1, expected_http_status: 200, state: "closed"} 37 | # Doesn't do much, just make sure this step returns successfully. 38 | - leave_network: {from: 2} 39 | -------------------------------------------------------------------------------- /raiden/tests/scenarios/pfs2_simple_no_path.yaml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | settings: 4 | gas_price: "fast" 5 | chain: any 6 | services: 7 | pfs: 8 | # url: https://pfs-kovan.services-dev.raiden.network 9 | url: http://localhost:6000 10 | udc: 11 | enable: true 12 | token: 13 | deposit: true 14 | 15 | token: 16 | 17 | nodes: 18 | mode: managed 19 | count: 4 20 | ## add path to Raiden virtual env 21 | 22 | default_options: 23 | gas-price: fast 24 | environment-type: development 25 | routing-mode: pfs 26 | pathfinding-max-paths: 5 27 | pathfinding-max-fee: 10 28 | 29 | ## This is the PFS1 scenario. It creates a network with topology A <-> B <-> C <-> D and checks 30 | ## whether a path is returned. 31 | 32 | scenario: 33 | serial: 34 | tasks: 35 | - parallel: 36 | name: "Open channels" 37 | tasks: 38 | - open_channel: {from: 0, to: 1, total_deposit: 1000} 39 | - open_channel: {from: 1, to: 2, total_deposit: 1000} 40 | - open_channel: {from: 2, to: 3, total_deposit: 1000} 41 | - serial: 42 | name: "Test providing routes" 43 | tasks: 44 | # Check that the PFS returns a path from A to D 45 | - assert_pfs_routes: {from: 3, to: 0, amount: 10, expected_paths: 0} 46 | 47 | ## Check that the path is indeed the expected one 48 | - assert_pfs_history: 49 | source: 3 50 | request_count: 1 51 | target: 0 52 | -------------------------------------------------------------------------------- /raiden/tests/scenarios/pfs5_too_low_capacity.yaml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | settings: 4 | gas_price: "fast" 5 | chain: any 6 | services: 7 | pfs: 8 | # url: https://pfs-kovan.services-dev.raiden.network 9 | url: http://localhost:6000 10 | udc: 11 | enable: true 12 | token: 13 | deposit: true 14 | 15 | token: 16 | 17 | nodes: 18 | mode: managed 19 | count: 5 20 | ## add path to Raiden virtual env 21 | 22 | default_options: 23 | gas-price: fast 24 | environment-type: development 25 | routing-mode: pfs 26 | pathfinding-max-paths: 5 27 | pathfinding-max-fee: 10 28 | 29 | ## This is the PFS5 scenario. It creates a network with topology A <-> B <-> C <-> D and A <-> E <-> D 30 | ## where AED doesn't have enough capacity to do the transfer. 31 | 32 | scenario: 33 | serial: 34 | tasks: 35 | - parallel: 36 | name: "Open channels" 37 | tasks: 38 | - open_channel: {from: 0, to: 1, total_deposit: 1000} 39 | - open_channel: {from: 1, to: 2, total_deposit: 1000} 40 | - open_channel: {from: 2, to: 3, total_deposit: 1000} 41 | # Setup alternative (best) path 42 | - open_channel: {from: 0, to: 4, total_deposit: 1000} 43 | - open_channel: {from: 4, to: 3, total_deposit: 5} 44 | - serial: 45 | name: "Test providing routes" 46 | tasks: 47 | # Check that the PFS returns two paths from A to D 48 | - assert_pfs_routes: {from: 0, to: 3, amount: 10, expected_paths: 1} 49 | 50 | ## Check that the paths are indeed the expected ones 51 | - assert_pfs_history: 52 | source: 0 53 | request_count: 1 54 | target: 3 55 | expected_routes: 56 | - [0, 1, 2, 3] 57 | -------------------------------------------------------------------------------- /raiden/tests/smart_contracts/RpcTest.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.5.4; 2 | 3 | contract RpcTest { 4 | function fail() pure public { 5 | require(false); 6 | } 7 | 8 | function ret() pure public returns (uint) { 9 | return 1; 10 | } 11 | 12 | function loop(uint reps) pure public returns (uint) { 13 | uint result = 0; 14 | for (uint i=0; iB" 67 | assert SingleByte.fields_spec == [byte] 68 | -------------------------------------------------------------------------------- /raiden/tests/unit/test_notifyingqueue.py: -------------------------------------------------------------------------------- 1 | import gevent 2 | from gevent.event import Event 3 | 4 | from raiden.network.transport.udp.udp_utils import event_first_of 5 | from raiden.utils.notifying_queue import NotifyingQueue 6 | 7 | 8 | def add_element_to_queue(queue, element): 9 | queue.put(element) 10 | 11 | 12 | def test_copy(): 13 | queue = NotifyingQueue() 14 | assert queue.copy() == [] 15 | 16 | queue.put(1) 17 | assert queue.copy() == [1] 18 | assert queue.peek() == 1, "copy must preserve the queue" 19 | 20 | queue.put(2) 21 | assert queue.copy() == [1, 2], "copy must preserve the items order" 22 | 23 | 24 | def test_event_must_be_set(): 25 | queue = NotifyingQueue() 26 | event_stop = Event() 27 | 28 | data_or_stop = event_first_of(queue, event_stop) 29 | 30 | spawn_after_seconds = 1 31 | element = 1 32 | gevent.spawn_later(spawn_after_seconds, add_element_to_queue, queue, element) 33 | assert data_or_stop.wait() 34 | 35 | 36 | def test_not_empty(): 37 | queue = NotifyingQueue(items=[1, 2]) 38 | assert queue.is_set() 39 | -------------------------------------------------------------------------------- /raiden/tests/unit/test_rpc.py: -------------------------------------------------------------------------------- 1 | from raiden.constants import EthClient 2 | from raiden.network.rpc.smartcontract_proxy import ClientErrorInspectResult, inspect_client_error 3 | 4 | 5 | def test_inspect_client_error(): 6 | """Regression test for issue https://github.com/raiden-network/raiden/issues/3005""" 7 | errorstr = ( 8 | "{'code': -32015, 'message': 'Transaction execution error.', 'data': " 9 | "'Internal(\"Requires higher than upper limit of 80000000\")'}" 10 | ) 11 | exception = ValueError(errorstr) 12 | 13 | result = inspect_client_error(exception, EthClient.PARITY) 14 | assert result == ClientErrorInspectResult.ALWAYS_FAIL 15 | -------------------------------------------------------------------------------- /raiden/tests/unit/test_state.py: -------------------------------------------------------------------------------- 1 | from raiden.transfer.state import TransactionChannelNewBalance, TransactionOrder 2 | 3 | 4 | def test_transaction_channel_new_balance_ordering(): 5 | a = TransactionChannelNewBalance(bytes(1), 1, 1) 6 | b = TransactionChannelNewBalance(bytes(2), 2, 2) 7 | assert a != b 8 | assert a < b 9 | assert b > a 10 | 11 | a = TransactionChannelNewBalance(bytes(1), 1, 1) 12 | b = TransactionChannelNewBalance(bytes(2), 2, 1) 13 | assert a != b 14 | assert a < b 15 | assert b > a 16 | 17 | a = TransactionChannelNewBalance(bytes(3), 3, 3) 18 | b = TransactionChannelNewBalance(bytes(3), 3, 3) 19 | assert a == b 20 | assert not a > b 21 | assert not b > a 22 | 23 | 24 | def test_transaction_order_ordering(): 25 | a = TransactionOrder(1, TransactionChannelNewBalance(bytes(1), 1, 1)) 26 | b = TransactionOrder(2, TransactionChannelNewBalance(bytes(2), 2, 2)) 27 | assert a != b 28 | assert a < b 29 | assert b > a 30 | 31 | a = TransactionOrder(1, TransactionChannelNewBalance(bytes(1), 1, 1)) 32 | b = TransactionOrder(2, TransactionChannelNewBalance(bytes(2), 2, 1)) 33 | assert a != b 34 | assert a < b 35 | assert b > a 36 | 37 | a = TransactionOrder(3, TransactionChannelNewBalance(bytes(3), 3, 3)) 38 | b = TransactionOrder(3, TransactionChannelNewBalance(bytes(3), 3, 3)) 39 | assert a == b 40 | assert not a > b 41 | assert not b > a 42 | 43 | a = TransactionOrder(1, TransactionChannelNewBalance(bytes(1), 1, 1)) 44 | b = TransactionOrder(2, TransactionChannelNewBalance(bytes(1), 1, 1)) 45 | assert a != b 46 | assert a < b 47 | assert b > a 48 | -------------------------------------------------------------------------------- /raiden/tests/unit/transfer/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/tests/unit/transfer/__init__.py -------------------------------------------------------------------------------- /raiden/tests/unit/transfer/mediated_transfer/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/tests/unit/transfer/mediated_transfer/__init__.py -------------------------------------------------------------------------------- /raiden/tests/unit/transfer/mediated_transfer/test_events.py: -------------------------------------------------------------------------------- 1 | from raiden.tests.utils import factories 2 | from raiden.transfer.mediated_transfer.events import SendRefundTransfer 3 | 4 | 5 | def test_send_refund_transfer_contains_balance_proof(): 6 | recipient = factories.make_address() 7 | transfer = factories.create(factories.LockedTransferUnsignedStateProperties()) 8 | message_identifier = 1 9 | channel_identifier = factories.make_channel_identifier() 10 | event = SendRefundTransfer( 11 | recipient=recipient, 12 | channel_identifier=channel_identifier, 13 | message_identifier=message_identifier, 14 | transfer=transfer, 15 | ) 16 | 17 | assert hasattr(event, "balance_proof") 18 | assert SendRefundTransfer.from_dict(event.to_dict()) == event 19 | -------------------------------------------------------------------------------- /raiden/tests/unit/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/tests/unit/utils/__init__.py -------------------------------------------------------------------------------- /raiden/tests/unit/utils/lighclient/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/tests/unit/utils/lighclient/__init__.py -------------------------------------------------------------------------------- /raiden/tests/unit/utils/lighclient/onboarding/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/tests/unit/utils/lighclient/onboarding/__init__.py -------------------------------------------------------------------------------- /raiden/tests/unit/utils/lighclient/onboarding/lightclient_inputs.py: -------------------------------------------------------------------------------- 1 | from eth_utils import encode_hex, decode_hex 2 | from raiden.utils.signer import LocalSigner 3 | 4 | private_key = decode_hex('0x63E5F0F39A21A5BA20AE69D02D20FAFF0F164763062D39CA183A91CC549D142A') 5 | display_name_to_sign = "@0x7ca28d3d760b4aa2b79e8d42cbdc187c7df9af40:raidentransport.mycryptoapi.com" 6 | password_to_sign = "raidentransport.mycryptoapi.com" 7 | seed_retry = "seed" 8 | 9 | signer = LocalSigner(private_key) 10 | 11 | print(f'signed_seed_retry: {encode_hex(signer.sign(seed_retry.encode()))}') 12 | print(f'signed_display_name: {encode_hex(signer.sign(display_name_to_sign.encode()))}') 13 | print(f'signed_password: {encode_hex(signer.sign(password_to_sign.encode()))}') 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /raiden/tests/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/tests/utils/__init__.py -------------------------------------------------------------------------------- /raiden/tests/utils/app.py: -------------------------------------------------------------------------------- 1 | import os 2 | import os.path 3 | 4 | from raiden.constants import RAIDEN_DB_VERSION 5 | 6 | 7 | def database_from_privatekey(base_dir, app_number): 8 | """ Format a database path based on the private key and app number. """ 9 | dbpath = os.path.join(base_dir, f"app{app_number}", f"v{RAIDEN_DB_VERSION}_log.db") 10 | os.makedirs(os.path.dirname(dbpath)) 11 | 12 | return dbpath 13 | -------------------------------------------------------------------------------- /raiden/tests/utils/client.py: -------------------------------------------------------------------------------- 1 | from eth_utils import to_checksum_address 2 | 3 | from raiden.tests.utils.factories import HOP1 4 | 5 | 6 | def burn_eth(raiden_service, amount_to_leave=0): 7 | """Burns all the ETH on the account of the given raiden service""" 8 | address = to_checksum_address(raiden_service.address) 9 | client = raiden_service.chain.client 10 | web3 = client.web3 11 | gas_price = web3.eth.gasPrice 12 | value = web3.eth.getBalance(address) - gas_price * (21000 + amount_to_leave) 13 | transaction_hash = client.send_transaction(to=HOP1, value=value, startgas=21000) 14 | client.poll(transaction_hash) 15 | -------------------------------------------------------------------------------- /raiden/tests/utils/detect_failure.py: -------------------------------------------------------------------------------- 1 | import gevent 2 | from gevent.event import AsyncResult 3 | 4 | 5 | def raise_on_failure(raiden_apps, test_function, **kwargs): 6 | """Wait on the result for the test function and any of the apps. 7 | 8 | This utility should be used for happy path testing with more than one app. 9 | This will raise if any of the apps is killed. 10 | """ 11 | result = AsyncResult() 12 | 13 | for app in raiden_apps: 14 | assert app.raiden 15 | app.raiden.link(result) 16 | 17 | gevent.spawn(test_function, **kwargs).link(result) 18 | result.get() 19 | -------------------------------------------------------------------------------- /raiden/tests/utils/migrations.py: -------------------------------------------------------------------------------- 1 | from hexbytes import HexBytes 2 | 3 | from raiden.tests.utils.factories import make_block_hash 4 | from raiden.utils.typing import Any, Dict, Tuple 5 | 6 | 7 | class FakeEth: 8 | def __init__(self, block_to_blockhash: Dict[int, Any]): 9 | self.block_to_blockhash = block_to_blockhash 10 | 11 | def getBlock(self, number: int) -> Dict[str, Any]: 12 | block_hash = self.block_to_blockhash[number] 13 | return {"hash": block_hash} 14 | 15 | 16 | class FakeWeb3: 17 | def __init__(self, block_to_blockhash: Dict[int, Any]): 18 | self.eth = FakeEth(block_to_blockhash) 19 | 20 | 21 | def create_fake_web3_for_block_hash(number_of_blocks: int = 0) -> Tuple[FakeWeb3, Dict[int, Any]]: 22 | block_to_blockhash = {} 23 | for block in range(0, number_of_blocks): 24 | block_to_blockhash[block] = HexBytes(make_block_hash()) 25 | 26 | fake_web3 = FakeWeb3(block_to_blockhash) 27 | 28 | return fake_web3, block_to_blockhash 29 | -------------------------------------------------------------------------------- /raiden/transfer/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/transfer/__init__.py -------------------------------------------------------------------------------- /raiden/transfer/mediated_transfer/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/transfer/mediated_transfer/__init__.py -------------------------------------------------------------------------------- /raiden/transfer/queue_identifier.py: -------------------------------------------------------------------------------- 1 | from eth_utils import to_canonical_address, to_checksum_address 2 | 3 | from raiden.utils import pex 4 | from raiden.utils.typing import Address, Any, ChannelID, Dict 5 | 6 | 7 | class QueueIdentifier: 8 | def __init__( 9 | self, 10 | recipient: Address, 11 | channel_identifier: ChannelID, 12 | ): 13 | self.recipient = recipient 14 | self.channel_identifier = channel_identifier 15 | 16 | def __repr__(self): 17 | return ''.format( 18 | pex(self.recipient), 19 | self.channel_identifier, 20 | ) 21 | 22 | def __eq__(self, other): 23 | return ( 24 | isinstance(other, QueueIdentifier) and 25 | self.recipient == other.recipient and 26 | self.channel_identifier == other.channel_identifier 27 | ) 28 | 29 | def __ne__(self, other): 30 | return not self.__eq__(other) 31 | 32 | def __hash__(self): 33 | return hash((self.recipient, self.channel_identifier)) 34 | 35 | def to_dict(self) -> Dict[str, Any]: 36 | return { 37 | 'recipient': to_checksum_address(self.recipient), 38 | 'channel_identifier': self.channel_identifier, 39 | } 40 | 41 | @classmethod 42 | def from_dict(cls, data: Dict[str, Any]) -> 'QueueIdentifier': 43 | restored = cls( 44 | recipient=to_canonical_address(data['recipient']), 45 | channel_identifier=data['channel_identifier'], 46 | ) 47 | 48 | return restored 49 | -------------------------------------------------------------------------------- /raiden/transfer/secret_registry.py: -------------------------------------------------------------------------------- 1 | from raiden.transfer.architecture import Event 2 | from raiden.transfer.channel import get_status 3 | from raiden.transfer.events import ContractSendSecretReveal 4 | from raiden.transfer.state import ( 5 | CHANNEL_STATE_CLOSED, 6 | CHANNEL_STATES_PRIOR_TO_CLOSED, 7 | NettingChannelState, 8 | ) 9 | from raiden.utils.typing import BlockExpiration, BlockHash, List, Secret, T_Secret 10 | 11 | 12 | def events_for_onchain_secretreveal( 13 | channel_state: NettingChannelState, 14 | secret: Secret, 15 | expiration: BlockExpiration, 16 | block_hash: BlockHash, 17 | ) -> List[Event]: 18 | events: List[Event] = list() 19 | 20 | if not isinstance(secret, T_Secret): 21 | raise ValueError("secret must be a Secret instance") 22 | 23 | if get_status(channel_state) in CHANNEL_STATES_PRIOR_TO_CLOSED + (CHANNEL_STATE_CLOSED,): 24 | reveal_event = ContractSendSecretReveal( 25 | expiration=expiration, secret=secret, triggered_by_block_hash=block_hash 26 | ) 27 | events.append(reveal_event) 28 | 29 | return events 30 | -------------------------------------------------------------------------------- /raiden/ui/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/ui/__init__.py -------------------------------------------------------------------------------- /raiden/ui/config.py: -------------------------------------------------------------------------------- 1 | import inspect 2 | from enum import Enum 3 | 4 | import pytoml 5 | 6 | from raiden.utils.serialization import serialize_bytes 7 | 8 | builtin_types = (int, str, bool, tuple) 9 | 10 | 11 | def _clean_non_serializables(data): 12 | copy = {} 13 | for key, value in data.items(): 14 | if callable(value): 15 | continue 16 | 17 | if hasattr(value, "to_dict"): 18 | value = value.to_dict() 19 | 20 | if isinstance(value, dict): 21 | value = _clean_non_serializables(value) 22 | 23 | if isinstance(value, bytes): 24 | value = serialize_bytes(value) 25 | 26 | if isinstance(value, tuple): 27 | value = list(value) 28 | 29 | if isinstance(key, Enum): 30 | key = key.name 31 | 32 | if isinstance(value, Enum): 33 | value = value.value 34 | 35 | if value and not isinstance(value, builtin_types): 36 | try: 37 | pytoml.dumps({key: value}) 38 | except RuntimeError: 39 | continue 40 | 41 | copy[key] = value 42 | return copy 43 | 44 | 45 | def dump_config(config): 46 | print(pytoml.dumps({"configs": _clean_non_serializables(config)})) 47 | print() 48 | 49 | 50 | def dump_cmd_options(options): 51 | print(pytoml.dumps({"options": _clean_non_serializables(options)})) 52 | print() 53 | 54 | 55 | def dump_module(header, module): 56 | attribs = dict() 57 | for name, value in inspect.getmembers(module): 58 | if name.isupper(): 59 | attribs[name] = value 60 | 61 | attribs = _clean_non_serializables(attribs) 62 | 63 | print(pytoml.dumps({header: attribs})) 64 | print() 65 | -------------------------------------------------------------------------------- /raiden/ui/explorer.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import structlog 3 | from datetime import datetime 4 | 5 | log = structlog.get_logger(__name__) 6 | 7 | 8 | def register(explorer_endpoint, rsk_address, rns_domain): 9 | try: 10 | 11 | if rns_domain is None: 12 | rns_domain = '' 13 | 14 | data_registry = {'node_address': rsk_address, 15 | 'rns_address': rns_domain, 16 | 'last_alive_signal': datetime.utcnow().isoformat()} 17 | 18 | response = requests.post(explorer_endpoint + 'luminoNode/', json=data_registry) 19 | if response.status_code == 200: 20 | log.info("Succesfully registered into Lumino Explorer") 21 | else: 22 | log.info("Warning: There was an error registering into Lumino Explorer. Status: " + str(response.status_code)) 23 | except requests.exceptions.RequestException as e: 24 | log.info("Warning: Could not connect to Lumino Explorer. Your node will not be registered.") 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /raiden/utils/ethereum_clients.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | from raiden.constants import EthClient 4 | from raiden.utils.typing import Optional, Tuple 5 | 6 | 7 | def is_supported_client(client_version: str,) -> Tuple[bool, Optional[EthClient]]: 8 | if client_version.startswith("Parity"): 9 | matches = re.search(r"//v(\d+)\.(\d+)\.(\d+)", client_version) 10 | if matches is None: 11 | return False, None 12 | major, minor, patch = [int(x) for x in matches.groups()] 13 | if (major, minor, patch) >= (1, 7, 6): 14 | return True, EthClient.PARITY 15 | elif client_version.startswith("Geth"): 16 | matches = re.search(r"/v(\d+)\.(\d+)\.(\d+)", client_version) 17 | if matches is None: 18 | return False, None 19 | major, minor, patch = [int(x) for x in matches.groups()] 20 | if (major, minor, patch) >= (1, 7, 2): 21 | return True, EthClient.GETH 22 | elif client_version.startswith('RskJ'): 23 | return True, EthClient.GETH 24 | return False, None 25 | -------------------------------------------------------------------------------- /raiden/utils/namehash/namehash.py: -------------------------------------------------------------------------------- 1 | import codecs 2 | import functools 3 | 4 | from sha3 import keccak_256 as sha3_256 5 | 6 | 7 | def is_bytes(value): 8 | return isinstance(value, (bytes, bytearray)) 9 | 10 | 11 | def combine(f, g): 12 | return lambda x: f(g(x)) 13 | 14 | 15 | def compose(*functions): 16 | return functools.reduce(combine, functions, lambda x: x) 17 | 18 | 19 | def sha3(value): 20 | return sha3_256(value).digest() 21 | 22 | 23 | def _sub_hash(value, label): 24 | return sha3(value + sha3(label)) 25 | 26 | 27 | def namehash(name, encoding=None): 28 | """ 29 | Implementation of the namehash algorithm from EIP137. 30 | """ 31 | node = b'\x00' * 32 32 | if name: 33 | if encoding is None: 34 | if is_bytes(name): 35 | encoded_name = name 36 | else: 37 | encoded_name = codecs.encode(name, 'utf8') 38 | else: 39 | encoded_name = codecs.encode(name, encoding) 40 | 41 | labels = encoded_name.split(b'.') 42 | 43 | return compose(*( 44 | functools.partial(_sub_hash, label=label) 45 | for label 46 | in labels 47 | ))(node) 48 | return node -------------------------------------------------------------------------------- /raiden/utils/notifying_queue.py: -------------------------------------------------------------------------------- 1 | from typing import Iterable, List, TypeVar 2 | 3 | from gevent.event import Event 4 | from gevent.queue import Queue 5 | 6 | T = TypeVar("T") 7 | 8 | 9 | class NotifyingQueue(Event): 10 | def __init__(self, maxsize: int = None, items: Iterable[T] = ()) -> None: 11 | super().__init__() 12 | self._queue = Queue(maxsize, items) 13 | 14 | if items: 15 | self.set() 16 | 17 | def put(self, item: T) -> None: 18 | """ Add new item to the queue. """ 19 | self._queue.put(item) 20 | self.set() 21 | 22 | def get(self, block: bool = True, timeout: float = None) -> T: 23 | """ Removes and returns an item from the queue. """ 24 | value = self._queue.get(block, timeout) 25 | if self._queue.empty(): 26 | self.clear() 27 | return value 28 | 29 | def peek(self, block: bool = True, timeout: float = None) -> T: 30 | return self._queue.peek(block, timeout) 31 | 32 | def __len__(self) -> int: 33 | return len(self._queue) 34 | 35 | def copy(self) -> List[T]: 36 | """ Copies the current queue items. """ 37 | copy = self._queue.copy() 38 | 39 | result = list() 40 | while not copy.empty(): 41 | result.append(copy.get_nowait()) 42 | return result 43 | -------------------------------------------------------------------------------- /raiden/utils/rns.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | 4 | def is_rns_address(address)->bool: 5 | if isinstance(address, bytes): 6 | return re.search(r'\.', address.hex()) 7 | else: 8 | return re.search(r'\.', address) 9 | 10 | -------------------------------------------------------------------------------- /raiden/utils/rsk_gas_price_strategy/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/raiden/utils/rsk_gas_price_strategy/__init__.py -------------------------------------------------------------------------------- /raiden/utils/signing.py: -------------------------------------------------------------------------------- 1 | from typing import Any, List 2 | 3 | from eth_utils import decode_hex, keccak, remove_0x_prefix 4 | from web3.utils.abi import map_abi_data 5 | from web3.utils.encoding import hex_encode_abi_type 6 | from web3.utils.normalizers import abi_address_to_hex 7 | 8 | sha3 = keccak 9 | 10 | 11 | def pack_data(abi_types: List[str], values: List[Any]) -> bytes: 12 | """Normalize data and pack them into a byte array""" 13 | if len(abi_types) != len(values): 14 | raise ValueError( 15 | "Length mismatch between provided abi types and values. Got " 16 | "{0} types and {1} values.".format(len(abi_types), len(values)) 17 | ) 18 | 19 | normalized_values = map_abi_data([abi_address_to_hex], abi_types, values) 20 | 21 | return decode_hex( 22 | "".join( 23 | remove_0x_prefix(hex_encode_abi_type(abi_type, value)) 24 | for abi_type, value in zip(abi_types, normalized_values) 25 | ) 26 | ) 27 | -------------------------------------------------------------------------------- /raiden/utils/smart_contracts.py: -------------------------------------------------------------------------------- 1 | from eth_utils import to_canonical_address 2 | 3 | from raiden.network.rpc.client import JSONRPCClient 4 | from raiden.utils.typing import Address, Any, Tuple 5 | from raiden_contracts.contract_manager import ContractManager 6 | 7 | 8 | def deploy_contract_web3( 9 | contract_name: str, 10 | deploy_client: JSONRPCClient, 11 | contract_manager: ContractManager, 12 | constructor_arguments: Tuple[Any] = None, 13 | ) -> Address: 14 | compiled = {contract_name: contract_manager.get_contract(contract_name)} 15 | contract_proxy, _ = deploy_client.deploy_solidity_contract( 16 | contract_name=contract_name, 17 | all_contracts=compiled, 18 | constructor_parameters=constructor_arguments, 19 | ) 20 | return Address(to_canonical_address(contract_proxy.contract.address)) 21 | -------------------------------------------------------------------------------- /raiden/utils/timeout.py: -------------------------------------------------------------------------------- 1 | import gevent 2 | 3 | from raiden.raiden_service import RaidenService 4 | from raiden.utils.typing import BlockNumber, Callable 5 | from raiden.waiting import wait_for_block 6 | 7 | 8 | def _timeout_task( 9 | throw: Callable, 10 | exception_to_throw: Exception, 11 | raiden: RaidenService, 12 | block_number: BlockNumber, 13 | retry_timeout: float, 14 | ): 15 | wait_for_block(raiden, block_number, retry_timeout) 16 | throw(exception_to_throw) 17 | 18 | 19 | class BlockTimeout: 20 | def __init__( 21 | self, 22 | exception_to_throw, 23 | raiden: RaidenService, 24 | block_number: BlockNumber, 25 | retry_timeout: float, 26 | ) -> None: 27 | self.exception_to_throw = exception_to_throw 28 | self.raiden = raiden 29 | self.block_number = block_number 30 | self.retry_timeout = retry_timeout 31 | self._task = None 32 | 33 | def __enter__(self) -> None: 34 | self._task = gevent.spawn( 35 | _timeout_task, 36 | gevent.getcurrent().throw, 37 | self.exception_to_throw, 38 | self.raiden, 39 | self.block_number, 40 | self.retry_timeout, 41 | ) 42 | 43 | def __exit__(self, exc_type, exc_value, traceback): 44 | self._task.kill() 45 | -------------------------------------------------------------------------------- /readthedocs.yml: -------------------------------------------------------------------------------- 1 | build: 2 | image: latest 3 | 4 | python: 5 | version: 3.6 6 | -------------------------------------------------------------------------------- /requirements-dev.txt: -------------------------------------------------------------------------------- 1 | -r requirements.txt 2 | # Split out to allow quicker lint turnaround on CI 3 | -r requirements-lint.txt 4 | # split out to allow faster building of docs and to not require python 3.7 5 | # since they don't support it in RTD yet: https://github.com/rtfd/readthedocs.org/issues/4713 6 | -r requirements-docs.txt 7 | # Testing 8 | pytest==5.2.0 9 | pytest-cov==2.5.1 10 | pytest-random==0.02 11 | pytest-timeout==1.3.3 12 | pytest-select==0.1.2 13 | grequests==0.3.0 14 | pexpect==4.6.0 15 | hypothesis==3.88.3 16 | # Debugging 17 | pdbpp==0.9.2 18 | colour==0.1.5 19 | # Continuous Integration 20 | coverage==4.5.1 21 | # Release 22 | bump2version==0.5.8 23 | # Test support 24 | matrix-synapse==1.3.1 -------------------------------------------------------------------------------- /requirements-docs.txt: -------------------------------------------------------------------------------- 1 | # Documentation 2 | sphinx==1.6.7 3 | sphinx_rtd_theme==0.4.0 4 | sphinxcontrib-httpdomain==1.7.0 5 | sphinxcontrib-httpexample==0.8.1 6 | sphinxcontrib-images==0.7.0 7 | releases==1.6.1 8 | -------------------------------------------------------------------------------- /requirements-lint.txt: -------------------------------------------------------------------------------- 1 | autopep8==1.4.3 2 | flake8==3.7.5 3 | flake8-bugbear==18.8.0 4 | flake8-tuple==0.2.13 5 | isort==4.3.16 6 | readme-renderer==21.0 7 | pylint==2.1.1 8 | # Dependency of pylint, pinned until https://github.com/PyCQA/astroid/issues/651 is fixed 9 | astroid==2.1.0 10 | mypy==0.700 11 | black==19.3b0 12 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | cachetools==2.1.0 2 | coincurve==11.0.0 3 | colorama==0.3.9 4 | eth-keyfile==0.5.1 5 | eth-keys==0.2.1 6 | eth-utils==1.4.1 7 | filelock==3.0.8 8 | Flask-Cors==3.0.6 9 | Flask-RESTful==0.3.6 10 | Flask-WTF==0.14.2 11 | Flask==1.0.2 12 | gevent==1.3.6 13 | ipython<5.0.0 14 | marshmallow-polyfield==3.2 15 | marshmallow==2.15.4 16 | matrix-client==0.3.2 17 | miniupnpc==2.0.2 18 | mirakuru==1.0.0 19 | netifaces==0.10.7 20 | networkx==2.1 21 | psutil==5.6.6 22 | py-geth==2.1.0 23 | pysha3==1.0.2 24 | py-solc==3.2.0 25 | pystun-patched-for-raiden==0.1.0 26 | pytoml==0.1.19 27 | raiden-contracts==0.19.1 28 | raiden-webui==0.8.0 29 | requests==2.20.0 30 | structlog==18.2.0 31 | webargs==5.1.3 32 | python-dateutil==2.8.0 33 | apscheduler==3.6.0 34 | base58==0.2.5 35 | secp256k1==0.13.2 36 | bitstring==3.1.5 37 | eciespy==0.3.0 38 | #Web3 RSK compatible 39 | git+git://github.com/infuy/web3.py@rsk-4.8.2#egg=web3 -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [flake8] 2 | ignore = E731, E203, E402, W503, W504, C814 3 | max-line-length = 99 4 | exclude = build,dist,.git,.venv,tools/ansible/contrib 5 | 6 | [pep8] 7 | ignore = E731, E203, E402, W503, W504, C814 8 | max-line-length = 99 9 | 10 | [isort] 11 | line_length=99 12 | known_future_library=future 13 | known_first_party=raiden,raiden_contracts,scenario_player 14 | default_section=THIRDPARTY 15 | combine_as_imports=1 16 | # black compatibility 17 | multi_line_output=3 18 | include_trailing_comma=True 19 | force_grid_wrap=0 20 | use_parentheses=True 21 | 22 | [coverage:run] 23 | branch = True 24 | concurrency = gevent 25 | 26 | [coverage:report] 27 | omit = 28 | */.tox/* 29 | */.pyenv/* 30 | */tests/* 31 | */site-packages/* 32 | 33 | [tool:pytest] 34 | timeout = 540 35 | norecursedirs = node_modules 36 | ; Ignore warnings: 37 | ; - grequests monkeypatch 38 | ; - urllib3 unverified TLS connection 39 | filterwarnings = 40 | ignore::gevent.monkey.MonkeyPatchWarning 41 | ignore::urllib3.exceptions.InsecureRequestWarning 42 | 43 | [mypy] 44 | ignore_missing_imports = True 45 | # check_untyped_defs = True 46 | # disallow_untyped_defs = True 47 | warn_unused_configs = True 48 | warn_unused_ignores = True 49 | 50 | [mypy-raiden.tests.*] 51 | ignore_errors = True 52 | -------------------------------------------------------------------------------- /snap/snapcraft.yaml: -------------------------------------------------------------------------------- 1 | name: raiden 2 | version: git 3 | summary: Fast, cheap, scalable token transfers for Ethereum 4 | description: | 5 | The Raiden Network is an off-chain scaling solution, enabling near-instant, 6 | low-fee and scalable payments. It’s complementary to the Ethereum blockchain 7 | and works with any ERC20 compatible token. 8 | 9 | The Raiden project is work in progress. Its goal is to research state channel 10 | technology, define protocols and develop reference implementations. 11 | 12 | For more information please visit http://raiden.network/. 13 | 14 | grade: devel # must be 'stable' to release into candidate/stable channels 15 | confinement: devmode # use 'strict' once you have the right plugs and slots 16 | 17 | apps: 18 | raiden: 19 | command: raiden 20 | 21 | parts: 22 | raiden: 23 | source: . 24 | plugin: python 25 | python-version: python2 26 | prepare: | 27 | apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 2A518C819BE37D2C2031944D1C52189C923F6CA9 28 | add-apt-repository --yes ppa:ethereum/ethereum 29 | apt update 30 | apt install --yes solc 31 | build-packages: 32 | - libssl-dev 33 | - libpython2.7-dev 34 | after: [requirements] 35 | requirements: 36 | source: . 37 | plugin: python 38 | python-version: python2 39 | requirements: requirements.txt 40 | # XXX: https://bugs.launchpad.net/snapcraft/+bug/1712634 41 | prepare: rm setup.py 42 | -------------------------------------------------------------------------------- /tools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/tools/__init__.py -------------------------------------------------------------------------------- /tools/debugging/migrate_db.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | """ 4 | import click 5 | import gevent 6 | import structlog 7 | 8 | from raiden.exceptions import InvalidDBData, RaidenDBUpgradeError 9 | from raiden.storage import serialize, sqlite 10 | from raiden.utils.upgrades import UpgradeManager 11 | 12 | log = structlog.get_logger(__name__) 13 | 14 | database_path = "" 15 | 16 | 17 | def upgrade_db(current_version: int, new_version: int): 18 | log.debug(f'Upgrading database from v{current_version} to v{new_version}') 19 | # Prevent unique constraint error in DB when recording raiden "runs" 20 | gevent.sleep(1) 21 | manager = UpgradeManager( 22 | db_filename=database_path, 23 | current_version=current_version, 24 | new_version=new_version, 25 | ) 26 | try: 27 | manager.run() 28 | except (RaidenDBUpgradeError, InvalidDBData) as e: 29 | manager.restore_backup() 30 | log.error(f'Failed to upgrade database: {str(e)}') 31 | 32 | 33 | def migrate_db(storage): 34 | storage.register_upgrade_callback(upgrade_db) 35 | storage.maybe_upgrade() 36 | 37 | 38 | @click.command(help=__doc__) 39 | @click.argument( 40 | 'db-file', 41 | type=click.Path(exists=True), 42 | ) 43 | def main(db_file): 44 | global database_path 45 | database_path = db_file 46 | migrate_db( 47 | storage=sqlite.SQLiteStorage(db_file, serialize.JSONSerializer()), 48 | ) 49 | 50 | 51 | if __name__ == "__main__": 52 | main() 53 | -------------------------------------------------------------------------------- /tools/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | NODES_PER_MACHINE=2 4 | 5 | # list of IPs 6 | IP_ADDRESSES="127.0.0.1" 7 | 8 | DATADIR=ethereum 9 | TMPDIR=$(mktemp -d --tmpdir=.) 10 | GETH="geth --datadir ${DATADIR}" 11 | 12 | GENESIS_FILE=${DATADIR}/genesis.json 13 | SCENARIO_FILE=${DATADIR}/scenario.json 14 | GETH_COMMANDS_FILE=${DATADIR}/geth_commands.json 15 | STATE_FILE=${TMPDIR}/state_dump.json 16 | 17 | mkdir -p ${DATADIR} ${TMPDIR} 18 | 19 | ./config_builder.py build_scenario ${NODES_PER_MACHINE} ${IP_ADDRESSES} > ${SCENARIO_FILE} 20 | 21 | ./config_builder.py geth_commands ${DATADIR} ${IP_ADDRESSES} > ${GETH_COMMANDS_FILE} 22 | 23 | sed 's/^.*\(\[\"enode:.*\]\),.*$/\1/g' ${GETH_COMMANDS_FILE} > ${DATADIR}/static-nodes.json 24 | 25 | mkdir -p ${DATADIR}/keystore 26 | ./config_builder.py account_file > ${DATADIR}/keystore/default.json 27 | 28 | ./config_builder.py full_genesis ${NODES_PER_MACHINE} ${IP_ADDRESSES} --scenario ${SCENARIO_FILE} > ${GENESIS_FILE} 29 | 30 | sed 's/^.*\"raidenFlags\": \"\([^"]*\).*$/\1/g' ${GENESIS_FILE} > ${DATADIR}/raiden_flags.txt 31 | 32 | # for each node add a private key (will be iterated over to pass to raiden) 33 | ./config_builder.py accounts ${NODES_PER_MACHINE} ${IP_ADDRESSES} > ${DATADIR}/raiden_nodes.json 34 | 35 | geth --datadir ${DATADIR} init ${GENESIS_FILE} 36 | -------------------------------------------------------------------------------- /tools/dummy_resolver_server.py: -------------------------------------------------------------------------------- 1 | import json 2 | import logging 3 | from http.server import BaseHTTPRequestHandler, HTTPServer 4 | 5 | from eth_utils import to_bytes, to_hex 6 | 7 | from raiden.utils import sha3 8 | 9 | # The code below simulates XUD resolver functionality. 10 | # It should only be used for testing and should not be used in 11 | # run time or production. 12 | 13 | 14 | def resolve(request): 15 | 16 | preimage = None 17 | 18 | x_secret = "0x2ff886d47b156de00d4cad5d8c332706692b5b572adfe35e6d2f65e92906806e" 19 | x_secret_hash = to_hex(sha3(to_bytes(hexstr=x_secret))) 20 | 21 | if request["secret_hash"] == x_secret_hash: 22 | preimage = {"secret": x_secret} 23 | 24 | return preimage 25 | 26 | 27 | def serve(): 28 | class SimpleHTTPRequestHandler(BaseHTTPRequestHandler): 29 | def do_POST(self): 30 | try: 31 | content_len = int(self.headers.get("Content-Length")) 32 | body = self.rfile.read(content_len) 33 | 34 | preimage = resolve(json.loads(body.decode("utf8"))) 35 | if preimage is None: 36 | self.send_response(404) 37 | self.end_headers() 38 | else: 39 | response = to_bytes(text=json.dumps(preimage)) 40 | self.send_response(200) 41 | self.end_headers() 42 | self.wfile.write(response) 43 | except BaseException: 44 | self.send_response(400) 45 | self.end_headers() 46 | 47 | httpd = HTTPServer(("localhost", 8000), SimpleHTTPRequestHandler) 48 | httpd.serve_forever() 49 | 50 | 51 | if __name__ == "__main__": 52 | logging.basicConfig() 53 | serve() 54 | -------------------------------------------------------------------------------- /tools/genesis_builder.py: -------------------------------------------------------------------------------- 1 | from eth_utils import encode_hex 2 | from eth_utils.currency import denoms 3 | 4 | from raiden.tests.utils.genesis import GENESIS_STUB 5 | from raiden.utils import privatekey_to_address, sha3 6 | 7 | CLUSTER_NAME = b"raiden" 8 | ETHER = denoms.ether # pylint: disable=no-member 9 | 10 | 11 | def generate_accounts(seeds): 12 | """Create private keys and addresses for all seeds. 13 | """ 14 | return { 15 | seed: { 16 | "privatekey": encode_hex(sha3(seed)), 17 | "address": encode_hex(privatekey_to_address(sha3(seed))), 18 | } 19 | for seed in seeds 20 | } 21 | 22 | 23 | def mk_genesis(accounts, initial_alloc=ETHER * 100000000): 24 | """ 25 | Create a genesis-block dict with allocation for all `accounts`. 26 | 27 | :param accounts: list of account addresses (hex) 28 | :param initial_alloc: the amount to allocate for the `accounts` 29 | :return: genesis dict 30 | """ 31 | genesis = GENESIS_STUB.copy() 32 | genesis["extraData"] = encode_hex(CLUSTER_NAME) 33 | genesis["alloc"].update({account: {"balance": str(initial_alloc)} for account in accounts}) 34 | # add the one-privatekey account ("1" * 64) for convenience 35 | genesis["alloc"]["19e7e376e7c213b7e7e7e46cc70a5dd086daff2a"] = dict(balance=str(initial_alloc)) 36 | return genesis 37 | -------------------------------------------------------------------------------- /tools/pyinstaller_hooks/hook-Crypto.py: -------------------------------------------------------------------------------- 1 | import glob 2 | import os 3 | 4 | from PyInstaller.compat import EXTENSION_SUFFIXES 5 | from PyInstaller.utils.hooks import get_module_file_attribute 6 | 7 | """ 8 | Add Cryptodome (imports as Crypto) binary modules 9 | """ 10 | 11 | binaries = [] 12 | binary_module_names = ["Crypto.Cipher", "Crypto.Util", "Crypto.Hash", "Crypto.Protocol"] 13 | 14 | for module_name in binary_module_names: 15 | module_dir = os.path.dirname(get_module_file_attribute(module_name)) 16 | for ext in EXTENSION_SUFFIXES: 17 | module_bin = glob.glob(os.path.join(module_dir, "_*{}".format(ext))) 18 | for filename in module_bin: 19 | binaries.append((filename, module_name.replace(".", "/"))) 20 | -------------------------------------------------------------------------------- /tools/pyinstaller_hooks/hook-cytoolz.py: -------------------------------------------------------------------------------- 1 | hiddenimports = ["cytoolz.utils", "cytoolz._signatures"] 2 | -------------------------------------------------------------------------------- /tools/pyinstaller_hooks/hook-eth_hash.py: -------------------------------------------------------------------------------- 1 | hiddenimports = ["eth_hash.backends.pycryptodome"] 2 | -------------------------------------------------------------------------------- /tools/pyinstaller_hooks/hook-gevent.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | import gevent 4 | 5 | 6 | # This is temporarily needed until https://github.com/pyinstaller/pyinstaller/pull/3534 is fixed 7 | def _get_gevent_imports(): 8 | package_path = Path(gevent.__file__).parent 9 | 10 | imports = [] 11 | imports.extend( 12 | "gevent.{}".format( 13 | str(module.relative_to(package_path)).replace(".py", "").replace("/", ".") 14 | ) 15 | for module in package_path.glob("**/*.py") 16 | ) 17 | imports.extend( 18 | "gevent.{}".format( 19 | str(module.relative_to(package_path)).partition(".")[0].replace("/", ".") 20 | ) 21 | for module in package_path.glob("**/*.so") 22 | ) 23 | 24 | return imports 25 | 26 | 27 | hiddenimports = _get_gevent_imports() 28 | -------------------------------------------------------------------------------- /tools/pyinstaller_hooks/hook-raiden.py: -------------------------------------------------------------------------------- 1 | import glob 2 | import os 3 | import sys 4 | 5 | import pkg_resources 6 | 7 | datas = [] 8 | binaries = [] 9 | 10 | 11 | # This is only needed until https://github.com/pyinstaller/pyinstaller/issues/3033 is fixed 12 | def copy_metadata(package_name): 13 | dist = pkg_resources.get_distribution(package_name) 14 | metadata_dir = dist.egg_info 15 | return [(metadata_dir, metadata_dir[len(dist.location) + len(os.sep) :])] 16 | 17 | 18 | # Add metadata of all required packages to allow pkg_resources.require() to work 19 | required_packages = [("raiden", [])] 20 | while required_packages: 21 | req_name, req_extras = required_packages.pop() 22 | for req in pkg_resources.get_distribution(req_name).requires(req_extras): 23 | required_packages.append((req.project_name, list(req.extras))) 24 | try: 25 | datas.extend(copy_metadata(req_name)) 26 | except AssertionError: 27 | pass 28 | 29 | if sys.platform == "darwin": 30 | # Include newer (Homebrew) OpenSSL libs if available 31 | openssl_lib_paths = ["/usr/local/Cellar/openssl/"] 32 | for path in openssl_lib_paths: 33 | if os.path.exists(path): 34 | libpath = os.path.join(path, os.listdir(path)[-1], "lib") 35 | for lib in glob.glob("{}/*.dylib".format(libpath)): 36 | binaries.append((lib, ".")) 37 | -------------------------------------------------------------------------------- /tools/pyinstaller_hooks/hook-raiden_contracts.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pathlib import Path 3 | 4 | from raiden_contracts.contract_manager import _BASE 5 | 6 | datas = [] 7 | 8 | 9 | for subdir, _, _ in os.walk(_BASE): 10 | for file_path in Path(subdir).glob("*.json"): 11 | datas.append((str(file_path), os.path.basename(subdir))) 12 | -------------------------------------------------------------------------------- /tools/pyinstaller_hooks/hook-raiden_webui.py: -------------------------------------------------------------------------------- 1 | from PyInstaller.utils.hooks import collect_data_files 2 | 3 | datas = collect_data_files("raiden_webui") 4 | -------------------------------------------------------------------------------- /tools/pyinstaller_hooks/runtime_encoding.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | """ 4 | File io can fail if there is no locale set. This adds a fallback to `en_US.UTF-8`. 5 | """ 6 | 7 | if not any(k in os.environ for k in ["LC_CTYPE", "LC_ALL", "LANG"]): 8 | print("Warning: No locale set. Falling back to 'en_US.UTF-8'.") 9 | os.environ["LANG"] = "en_US.UTF-8" 10 | -------------------------------------------------------------------------------- /tools/pyinstaller_hooks/runtime_gevent_monkey.py: -------------------------------------------------------------------------------- 1 | from gevent.monkey import patch_all 2 | 3 | patch_all() 4 | -------------------------------------------------------------------------------- /tools/pyinstaller_hooks/runtime_raiden_contracts.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from pathlib import Path 3 | 4 | from raiden_contracts import contract_manager 5 | 6 | # `sys._MEIPASS` is the root of the extracted pyinstaller bundle 7 | base_path = Path(sys._MEIPASS) # pylint: disable=no-member 8 | 9 | # Patch location of compiled contracts. 10 | contract_manager._BASE = base_path 11 | -------------------------------------------------------------------------------- /tools/pylint/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/tools/pylint/__init__.py -------------------------------------------------------------------------------- /tools/pylint/assert_checker.py: -------------------------------------------------------------------------------- 1 | from pylint.checkers import BaseChecker 2 | from pylint.interfaces import IAstroidChecker 3 | 4 | ASSERT_ID = "assert-message" 5 | ASSERT_MSG = "Every assert must have a message describing the error to aid debugging" 6 | 7 | 8 | def register(linter): 9 | linter.register_checker(AssertMessage(linter)) 10 | 11 | 12 | class AssertMessage(BaseChecker): 13 | __implements__ = IAstroidChecker 14 | 15 | name = "assert" 16 | priority = -1 17 | msgs = {"E6492": (ASSERT_MSG, ASSERT_ID, "Assert without message.")} 18 | 19 | def visit_assert(self, node): 20 | if len(list(node.get_children())) != 2: 21 | self.add_message(ASSERT_ID, node=node) 22 | -------------------------------------------------------------------------------- /tools/scenario-player/README.rst: -------------------------------------------------------------------------------- 1 | Raiden Scenario Player 2 | ====================== 3 | 4 | Usage 5 | ----- 6 | 7 | Installation:: 8 | 9 | # in raiden/tools/scenario-player 10 | # Using the same virtualenv that is used for raiden is possibe 11 | pip install -r requirements.txt 12 | 13 | Help:: 14 | 15 | python -m scenario_player --help 16 | 17 | Running:: 18 | 19 | python -m scenario_player \ 20 | --keystore-file \ 21 | --password '' \ 22 | 23 | 24 | 25 | Scenario Definition 26 | ------------------- 27 | 28 | TODO 29 | 30 | See ``example-scenarios/scenario-basic.yaml``. 31 | -------------------------------------------------------------------------------- /tools/scenario-player/requirements.txt: -------------------------------------------------------------------------------- 1 | urwid>=2.0.1 2 | raiden>=0.10.0 3 | pyyaml==4.2b4 4 | -------------------------------------------------------------------------------- /tools/scenario-player/scenario_player/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsksmart/lumino/86327115cc5121d052f6077a477a043c0b03dfbf/tools/scenario-player/scenario_player/__init__.py -------------------------------------------------------------------------------- /tools/scenario-player/scenario_player/__main__.py: -------------------------------------------------------------------------------- 1 | from gevent import monkey 2 | 3 | monkey.patch_all() 4 | 5 | 6 | if __name__ == "__main__": 7 | from .main import main 8 | main(prog_name='python -m scenario_player') 9 | -------------------------------------------------------------------------------- /tools/scenario-player/scenario_player/exceptions.py: -------------------------------------------------------------------------------- 1 | class ScenarioError(Exception): 2 | pass 3 | 4 | 5 | class ScenarioTxError(ScenarioError): 6 | pass 7 | 8 | 9 | class TokenRegistrationError(ScenarioTxError): 10 | pass 11 | 12 | 13 | class ChannelError(ScenarioError): 14 | pass 15 | 16 | 17 | class TransferFailed(ScenarioError): 18 | pass 19 | 20 | 21 | class NodesUnreachableError(ScenarioError): 22 | pass 23 | 24 | 25 | class RESTAPIError(ScenarioError): 26 | pass 27 | 28 | 29 | class RESTAPIStatusMismatchError(ScenarioError): 30 | pass 31 | 32 | 33 | class UnknownTaskTypeError(ScenarioError): 34 | pass 35 | 36 | 37 | class ScenarioAssertionError(ScenarioError): 38 | pass 39 | -------------------------------------------------------------------------------- /tools/scenario-player/scenario_player/tasks/token_network.py: -------------------------------------------------------------------------------- 1 | from .raiden_api import RaidenAPIActionTask 2 | 3 | 4 | class JoinTokenNetwork(RaidenAPIActionTask): 5 | _name = 'join_network' 6 | _url_template = '{protocol}://{target_host}/api/v1/connections/{token_address}' 7 | _method = 'put' 8 | 9 | @property 10 | def _url_params(self): 11 | params = dict( 12 | token_address=self._runner.token_address, 13 | ) 14 | return params 15 | 16 | @property 17 | def _request_params(self): 18 | params = dict( 19 | funds=self._config.get('funds'), 20 | ) 21 | 22 | initial_channel_target = self._config.get('initial_channel_target') 23 | if initial_channel_target is not None: 24 | params['initial_channel_target'] = initial_channel_target 25 | joinable_funds_target = self._config.get('joinable_funds_target') 26 | if joinable_funds_target is not None: 27 | params['joinable_funds_target'] = joinable_funds_target 28 | 29 | return params 30 | 31 | 32 | class LeaveTokenNetwork(RaidenAPIActionTask): 33 | _name = 'leave_network' 34 | _url_template = '{protocol}://{target_host}/api/v1/connections/{token_address}' 35 | _method = 'delete' 36 | 37 | @property 38 | def _url_params(self): 39 | params = dict( 40 | token_address=self._runner.token_address, 41 | ) 42 | return params 43 | -------------------------------------------------------------------------------- /tools/testnet/.gitignore: -------------------------------------------------------------------------------- 1 | *.retry 2 | terraform.tfstate.backup 3 | .terraform/plugins 4 | -------------------------------------------------------------------------------- /tools/testnet/.terraform/terraform.tfstate: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "serial": 0, 4 | "lineage": "dd2cbb91-aaa0-4504-9a7a-dc882b8290fc", 5 | "backend": { 6 | "type": "s3", 7 | "config": { 8 | "bucket": "network.raiden.testnet.terraform.state", 9 | "key": "terraform.tfstate", 10 | "region": "us-east-1" 11 | }, 12 | "hash": 15080838683479066689 13 | }, 14 | "modules": [ 15 | { 16 | "path": [ 17 | "root" 18 | ], 19 | "outputs": {}, 20 | "resources": {}, 21 | "depends_on": [] 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /tools/testnet/ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | 3 | inventory = ./inventory/inventory.sh 4 | private_key_file = ./keys/id_raiden_testnet 5 | vault_password_file = ./keys/id_raiden_testnet 6 | remote_user = ubuntu 7 | host_key_checking = False 8 | nocows = 1 9 | forks = 50 10 | retry_files_enabled = False 11 | jinja2_extensions = jinja2.ext.do 12 | -------------------------------------------------------------------------------- /tools/testnet/data.tf: -------------------------------------------------------------------------------- 1 | data "aws_ami" "ubuntu1604" { 2 | most_recent = true 3 | 4 | filter { 5 | name = "name" 6 | values = ["${var.ami_name_filter}"] 7 | } 8 | 9 | filter { 10 | name = "virtualization-type" 11 | values = ["hvm"] 12 | } 13 | 14 | # Canonical 15 | owners = ["099720109477"] 16 | } 17 | -------------------------------------------------------------------------------- /tools/testnet/files/dockerfiles/empty/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM scratch 2 | MAINTAINER Ulrich Petri 3 | -------------------------------------------------------------------------------- /tools/testnet/files/dockerfiles/geth-testnet/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ethereum/client-go:v1.8.22 2 | MAINTAINER Ulrich Petri 3 | 4 | RUN \ 5 | apk add --update python3 python3-dev build-base && \ 6 | rm -rf /var/cache/apk/* && \ 7 | pip3 install web3 click 8 | 9 | RUN pip3 install requests 10 | 11 | ADD run.py /usr/bin/run.py 12 | 13 | ENTRYPOINT ["/usr/bin/run.py"] 14 | -------------------------------------------------------------------------------- /tools/testnet/files/dockerfiles/mkkeystore/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.7 2 | 3 | MAINTAINER Ulrich Petri 4 | 5 | RUN \ 6 | apt update && \ 7 | apt install -y libssl-dev build-essential automake pkg-config libtool libffi-dev libgmp-dev && \ 8 | pip3 install ethereum coincurve click && \ 9 | rm -rf /var/lib/apt/lists/* 10 | 11 | ADD mkkey.py /usr/bin/ 12 | 13 | ENTRYPOINT ["/usr/bin/mkkey.py"] 14 | -------------------------------------------------------------------------------- /tools/testnet/files/dockerfiles/raiden/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:2.7 2 | MAINTAINER Ulrich Petri 3 | 4 | ARG SOLC_RELEASE=0.4.21 5 | 6 | RUN \ 7 | apt update && \ 8 | apt install -y build-essential curl git libffi-dev libgmp-dev libssl-dev libtool pkg-config apt-transport-https lsb-release && \ 9 | apt update && \ 10 | apt install nodejs && \ 11 | rm -rf /var/lib/apt/lists/* && \ 12 | curl -L -o /usr/bin/solc https://github.com/ethereum/solidity/releases/download/v${SOLC_RELEASE}/solc-static-linux && \ 13 | chmod +x /usr/bin/solc 14 | 15 | # These are defined down here to avoid rebuilding the "apt" part on repo/branch change 16 | ARG REPO=raiden-network/raiden 17 | ARG BRANCH=master 18 | 19 | # This is a "hack" to automatically invalidate the cache in case there are new commits 20 | ADD https://api.github.com/repos/${REPO}/commits/${BRANCH} /dev/null 21 | RUN \ 22 | echo Cloning ${REPO}@${BRANCH} && \ 23 | git clone -b ${BRANCH} https://github.com/${REPO}.git /app && \ 24 | pip --version && \ 25 | pip install -r /app/requirements.txt -e /app && \ 26 | pip install python-logstash && \ 27 | rm -rf /root/.cache/pip 28 | 29 | WORKDIR /app 30 | 31 | ADD run_raiden.py /usr/local/bin 32 | ADD raiden /usr/local/bin 33 | ADD raiden_echo_node /usr/local/bin 34 | 35 | 36 | ENTRYPOINT ["/usr/local/bin/run_raiden.py"] 37 | -------------------------------------------------------------------------------- /tools/testnet/files/dockerfiles/raiden/run_raiden.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | import click 6 | 7 | ETH_RPC_ENDPOINT_ARG = "--eth-rpc-endpoint" 8 | 9 | 10 | @click.command() 11 | @click.option("--eth-nodes", required=True) 12 | @click.option("--seed", required=True) 13 | @click.option("--raiden-executable", default="raiden", show_default=True) 14 | @click.argument("raiden_args", nargs=-1) 15 | def main(eth_nodes, seed, raiden_executable, raiden_args): 16 | if ETH_RPC_ENDPOINT_ARG in raiden_args: 17 | raise RuntimeError("Argument conflict: {}".format(ETH_RPC_ENDPOINT_ARG)) 18 | eth_nodes = eth_nodes.split(",") 19 | offset = sum(ord(c) for c in seed) % len(eth_nodes) 20 | target_eth_node = eth_nodes[offset] 21 | raiden_args = [raiden_executable] + list(raiden_args) + [ETH_RPC_ENDPOINT_ARG, target_eth_node] 22 | print(" ".join(raiden_args)) 23 | # Ensure print is flushed - exec could swallow it 24 | sys.stdout.flush() 25 | os.execvp(raiden_args[0], raiden_args) 26 | 27 | 28 | if __name__ == "__main__": 29 | main() # pylint: disable=no-value-for-parameter 30 | -------------------------------------------------------------------------------- /tools/testnet/files/dockerfiles/scenario_player/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM brainbot/raiden 2 | 3 | MAINTAINER Ulrich Petri 4 | 5 | ADD scenario_player.py /usr/local/bin/transfer_generator.py 6 | ADD scenario-testnet-token.yml /usr/share 7 | 8 | ENTRYPOINT ["/usr/local/bin/transfer_generator.py"] 9 | -------------------------------------------------------------------------------- /tools/testnet/files/templates/eth_addresses.j2: -------------------------------------------------------------------------------- 1 | {% for item in groups['role_raiden'] %} 2 | 0x{{ hostvars[item]['keystore_content']['address'] }} 3 | {% endfor %} -------------------------------------------------------------------------------- /tools/testnet/inventory/inventory.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # cross platform compatible way to get temp dir location 4 | TMP=$(dirname $(mktemp -u)) 5 | # "Cache" state for one minute 6 | STATE_FILE="${TMP}/raiden-testnet-$(date +%Y%m%d%H%M).tfstate" 7 | if [ ! -f ${STATE_FILE} ]; then 8 | terraform state pull > ${STATE_FILE} 9 | fi 10 | exec terraform-inventory "$@" ${STATE_FILE} 11 | -------------------------------------------------------------------------------- /tools/testnet/keys/.gitignore: -------------------------------------------------------------------------------- 1 | id_* -------------------------------------------------------------------------------- /tools/testnet/library/docker_facts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from ansible.module_utils.basic import AnsibleModule 4 | 5 | HAVE_DOCKER = True 6 | try: 7 | from docker import APIClient 8 | except ImportError: 9 | try: 10 | from docker import Client as APIClient 11 | except ImportError: 12 | HAVE_DOCKER = False 13 | 14 | 15 | DOCUMENTATION = """ 16 | --- 17 | module: docker_facts 18 | short_description: Inject Docker info as facts. 19 | author: ulrich@brainbot.com 20 | """ 21 | 22 | EXAMPLES = """ 23 | - name: get docker facts 24 | docker_facts: 25 | """ 26 | 27 | 28 | def main(): 29 | ansible_module = AnsibleModule( 30 | argument_spec=dict(), 31 | supports_check_mode=True 32 | ) 33 | 34 | if not HAVE_DOCKER: 35 | ansible_module.fail_json(msg="Python library 'docker' missing.") 36 | 37 | try: 38 | ansible_module.exit_json( 39 | changed=False, 40 | ansible_facts={'docker': APIClient().info()} 41 | ) 42 | except Exception as ex: 43 | ansible_module.fail_json(msg=str(ex)) 44 | 45 | 46 | if __name__ == '__main__': 47 | main() 48 | -------------------------------------------------------------------------------- /tools/testnet/output.tf: -------------------------------------------------------------------------------- 1 | output "testnet-members-infrastructure" { 2 | value = ["${aws_instance.node_infrastructure.*.public_ip}"] 3 | } 4 | output "testnet-members-eth" { 5 | value = ["${aws_instance.node_eth.*.public_ip}"] 6 | } 7 | output "testnet-members-raiden-echo" { 8 | value = ["${aws_instance.node_raiden_echo.*.public_ip}"] 9 | } 10 | output "testnet-members-raiden" { 11 | value = ["${aws_instance.node_raiden.*.public_ip}"] 12 | } 13 | -------------------------------------------------------------------------------- /tools/testnet/playbook-get_eth_addresses.yml: -------------------------------------------------------------------------------- 1 | - hosts: role_raiden 2 | gather_facts: no 3 | roles: 4 | - keystore 5 | tasks: 6 | - template: 7 | src: files/templates/eth_addresses.j2 8 | dest: /tmp/testnet_eth_addresses 9 | delegate_to: 127.0.0.1 10 | run_once: true 11 | 12 | - debug: 13 | msg: "Output in /tmp/testnet_eth_addresses" 14 | delegate_to: 127.0.0.1 15 | run_once: true 16 | -------------------------------------------------------------------------------- /tools/testnet/playbook-remove_datadir.yml: -------------------------------------------------------------------------------- 1 | - hosts: role_eth 2 | gather_facts: no 3 | tags: 4 | - eth 5 | tasks: 6 | - name: Stop container 7 | docker_container: 8 | name: "{{ item }}" 9 | state: stopped 10 | ignore_errors: yes 11 | with_items: 12 | - geth 13 | - parity 14 | 15 | - name: Destroy eth data dir 16 | become: true 17 | file: 18 | name: "{{ data_volume_dir }}/{{ item }}" 19 | state: absent 20 | with_items: 21 | - geth 22 | - parity 23 | 24 | - name: Start container 25 | docker_container: 26 | name: "{{ eth_node_type }}" 27 | state: started 28 | ignore_errors: yes 29 | 30 | - hosts: role_raiden 31 | gather_facts: no 32 | tags: 33 | - raiden 34 | tasks: 35 | - name: Stop container 36 | docker_container: 37 | name: "raiden" 38 | state: stopped 39 | ignore_errors: yes 40 | 41 | - name: Destroy raiden data dir 42 | become: true 43 | file: 44 | name: "{{ raiden_root }}" 45 | state: absent 46 | 47 | - name: Start container 48 | docker_container: 49 | name: "raiden" 50 | state: started 51 | ignore_errors: yes 52 | -------------------------------------------------------------------------------- /tools/testnet/playbook-testnet.yml: -------------------------------------------------------------------------------- 1 | - hosts: name_raiden_testnet 2 | gather_facts: no 3 | become: yes 4 | roles: 5 | - ssh_keys 6 | - hostname 7 | - docker 8 | 9 | - hosts: role_eth 10 | gather_facts: no 11 | roles: 12 | - eth_node 13 | 14 | - hosts: role_raiden 15 | gather_facts: no 16 | roles: 17 | - raiden 18 | 19 | - hosts: role_infrastructure 20 | gather_facts: no 21 | roles: 22 | - logstash 23 | 24 | - hosts: name_raiden_testnet 25 | gather_facts: no 26 | roles: 27 | - role: motd_info 28 | display_groups: 29 | Eth: role_eth 30 | Raiden: role_raiden 31 | Infrastructure: role_infrastructure 32 | - role: hosts_file 33 | display_groups: 34 | Eth: role_eth 35 | Raiden: role_raiden 36 | Infrastructure: role_infrastructure 37 | 38 | - hosts: name_raiden_testnet 39 | gather_facts: no 40 | tasks: 41 | - debug: 42 | msg: "{{ private_ip }}: {{ hostname }}" 43 | -------------------------------------------------------------------------------- /tools/testnet/roles/data_volume/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: Create storage fs 2 | become: yes 3 | filesystem: 4 | dev: /dev/xvdb 5 | fstype: ext4 6 | 7 | - name: Mount storage fs 8 | become: yes 9 | mount: 10 | fstype: ext4 11 | path: "{{ data_volume_dir }}" 12 | src: /dev/xvdb 13 | state: mounted 14 | -------------------------------------------------------------------------------- /tools/testnet/roles/eth_node/meta/main.yml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - data_volume 3 | -------------------------------------------------------------------------------- /tools/testnet/roles/eth_node/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: Create eth node data dir 2 | become: true 3 | file: 4 | name: "{{ data_volume_dir }}/{{ item }}" 5 | state: directory 6 | owner: "{{ ansible_user }}" 7 | mode: 0770 8 | with_items: 9 | - geth 10 | - parity 11 | 12 | - name: Eth node (parity) docker container 13 | docker_container: 14 | name: parity 15 | state: "{{ 'started' if eth_node_type == 'parity' else 'absent' }}" 16 | restart_policy: always 17 | pull: yes 18 | image: "{{ docker_repo_eth_parity }}" 19 | ports: 20 | - "8545:8545" 21 | - "30303:30303" 22 | - "30303:30303/udp" 23 | volumes: 24 | - "{{ data_volume_dir }}/parity:/root/.local/share/io.parity.ethereum" 25 | command: 26 | - "--chain" 27 | - "ropsten" 28 | - "--warp" 29 | - "--jsonrpc-interface" 30 | - "0.0.0.0" 31 | - "--jsonrpc-hosts" 32 | - "all" 33 | - "--nat" 34 | - "extip:{{ ansible_host }}" 35 | 36 | - name: Eth node (geth) docker container 37 | docker_container: 38 | name: geth 39 | state: "{{ 'started' if eth_node_type == 'geth' else 'absent' }}" 40 | restart_policy: always 41 | pull: yes 42 | image: "{{ docker_repo_eth_geth }}" 43 | ports: 44 | - "8545:8545" 45 | - "30303:30303" 46 | - "30303:30303/udp" 47 | volumes: 48 | - "{{ data_volume_dir }}/geth:/root/.ethereum" 49 | -------------------------------------------------------------------------------- /tools/testnet/roles/hostname/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - set_fact: 2 | host_offset: "{% set ips = [] %}{% for host in groups['role_{}'.format(hostvars[inventory_hostname]['tags.Role'])] %}{% if hostvars[inventory_hostname].get('tags.Echo') == hostvars[host].get('tags.Echo') %}{% do ips.append(hostvars[host]['private_ip'] | ipaddr('int')) %}{% endif %}{% endfor %}{{ ips | min }}" 3 | 4 | - debug: 5 | var: host_offset 6 | 7 | - set_fact: 8 | hostname: "{{ hostvars[inventory_hostname]['tags.Role'].lower() }}{{ '_echo' if hostvars[inventory_hostname].get('tags.Echo') == 'true' else '' }}_{{ '{:04d}'.format(private_ip | ipaddr('int') - host_offset | int + 1) }}" 9 | 10 | - debug: 11 | var: hostname 12 | 13 | - name: Hostname 14 | hostname: 15 | name: "{{ hostname }}" 16 | 17 | - name: Hostname file 18 | become: yes 19 | template: 20 | src: templates/hostname.j2 21 | dest: /etc/hostname 22 | -------------------------------------------------------------------------------- /tools/testnet/roles/hostname/templates/hostname.j2: -------------------------------------------------------------------------------- 1 | {{ hostname }} -------------------------------------------------------------------------------- /tools/testnet/roles/hosts_file/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: Hosts file 2 | become: yes 3 | template: 4 | src: templates/hosts.j2 5 | dest: /etc/hosts 6 | mode: 0644 7 | -------------------------------------------------------------------------------- /tools/testnet/roles/hosts_file/templates/hosts.j2: -------------------------------------------------------------------------------- 1 | 127.0.0.1 localhost 2 | 3 | {% for name, group in display_groups.items()|sort %}{% for item in groups[group]|sort %} 4 | {{ hostvars[item]['private_ip'] }} {{ hostvars[item]['hostname'] }} 5 | {% endfor %}{% endfor %} 6 | -------------------------------------------------------------------------------- /tools/testnet/roles/keystore/defaults/main.yml: -------------------------------------------------------------------------------- 1 | keystore_root: "{{ raiden_root }}_keystore" 2 | keystore_file_date: 2017-07-01 3 | 4 | # `keystore_password` and `keystore_priv_seed` are in vault encrypted `vars/main.yml` 5 | -------------------------------------------------------------------------------- /tools/testnet/roles/keystore/templates/password.j2: -------------------------------------------------------------------------------- 1 | {{ keystore_password }} -------------------------------------------------------------------------------- /tools/testnet/roles/keystore/vars/main.yml: -------------------------------------------------------------------------------- 1 | $ANSIBLE_VAULT;1.1;AES256 2 | 64376139653464353430616438343866316338616534313731306237346166633163313536613737 3 | 3138646337303765663832383966353537363032346663310a653131653234646639643932366462 4 | 66393235353836336263386432323131376234386131323135393861646530623062636261353733 5 | 3239626530663338630a626164613366356635666436653736323237383062613463306532313739 6 | 32643062646537366262353339323534653964336466663135623666643663316435386562353032 7 | 63633036623133383465663434663538646665383561653736386463323938376262383865663766 8 | 32343834343533643331376561303939306331373761336139336239383062386338333938383235 9 | 66346361343439373065333439623761653266303063383834623632366237663964633965323330 10 | 33656331386463373664333432313032663562396531653963373366356365373538323764383730 11 | 37616165653638363837633961653239663932323766613432393336663838363066363666616463 12 | 31643734373233613637313039313835323961643735636239363930313232386164376466383261 13 | 32396562303633653365386132393663376637343861356665633664666365303636626535653332 14 | 65303330353838303662313933636265343635613266636631656464643663396563386230353461 15 | 3362303162316262613035386162393730333134363338373535 16 | -------------------------------------------------------------------------------- /tools/testnet/roles/logstash/files/logstash.conf: -------------------------------------------------------------------------------- 1 | input { 2 | udp { 3 | port => 9595 4 | codec => json 5 | } 6 | } 7 | 8 | output { 9 | elasticsearch { 10 | hosts => ["elasticsearch:9200"] 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tools/testnet/roles/logstash/meta/main.yml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - data_volume 3 | - traefik 4 | -------------------------------------------------------------------------------- /tools/testnet/roles/logstash/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: Logstash config dir 2 | become: yes 3 | file: 4 | path: /etc/logstash 5 | state: directory 6 | 7 | - name: Logstash config file 8 | become: yes 9 | copy: 10 | src: files/logstash.conf 11 | dest: /etc/logstash/logstash.conf 12 | 13 | - name: Elasticsearch container 14 | docker_container: 15 | name: elasticsearch 16 | restart_policy: always 17 | pull: yes 18 | image: "{{ docker_repo_elasticsearch }}" 19 | volumes: 20 | - "{{ data_volume_dir }}/es:/usr/share/elasticsearch/data" 21 | env: 22 | ES_JAVA_OPTS: "-Xms512m -Xmx512m" 23 | 24 | - name: Logstash docker container 25 | docker_container: 26 | name: logstash 27 | restart_policy: always 28 | pull: yes 29 | image: "{{ docker_repo_logstash }}" 30 | links: 31 | - elasticsearch:elasticsearch 32 | ports: 33 | - 9595:9595 34 | - 9595:9595/udp 35 | volumes: 36 | - /etc/logstash:/etc/logstash 37 | command: -f /etc/logstash/logstash.conf 38 | 39 | - name: Kibana docker container 40 | docker_container: 41 | name: kibana 42 | restart_policy: always 43 | pull: yes 44 | image: "{{ docker_repo_kibana }}" 45 | links: 46 | - elasticsearch:elasticsearch 47 | ports: 48 | - 5601:5601 49 | labels: 50 | traefik.enable: "true" 51 | traefik.frontend.rule: "Host:logs.{{ testnet_domain }}" 52 | traefik.frontend.entryPoints: "https" 53 | -------------------------------------------------------------------------------- /tools/testnet/roles/logstash/vars/main.yml: -------------------------------------------------------------------------------- 1 | docker_repo_logstash: "logstash:5.5.1" 2 | docker_repo_elasticsearch: "elasticsearch:5.5.1" 3 | docker_repo_kibana: "kibana:5.5.1" 4 | 5 | logstash_root: /etc/logstash 6 | -------------------------------------------------------------------------------- /tools/testnet/roles/motd_info/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - become: yes 2 | file: 3 | name: "/etc/update-motd.d/{{ item }}" 4 | state: absent 5 | with_items: 6 | - "10-help-text" 7 | - "51-cloudguest" 8 | - "90-updates-available" 9 | 10 | - name: Motd message 11 | become: yes 12 | template: 13 | src: templates/99-nodes.j2 14 | dest: /etc/update-motd.d/99-nodes 15 | mode: 0777 16 | -------------------------------------------------------------------------------- /tools/testnet/roles/motd_info/templates/99-nodes.j2: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo 4 | echo "Public IP: {{ ansible_host }}" 5 | echo "Private IP: {{ private_ip }}" 6 | echo "Role: {{ hostvars[inventory_hostname]['tags.Role'] }}" 7 | echo "Hostname: {{ hostname }}" 8 | {% if keystore_address is defined %}echo "Eth-Address: 0x{{ keystore_address }}"{% endif %} 9 | 10 | echo 11 | 12 | echo "Available nodes:" 13 | {% for name, group in display_groups.items()|sort %} 14 | echo "{{ name }}:" 15 | {% for item in groups[group]|sort %} 16 | echo " - {{ hostvars[item]['hostname'] }} - {{ hostvars[item]['private_ip'] }}" 17 | {% endfor %} 18 | echo 19 | {% endfor %} 20 | -------------------------------------------------------------------------------- /tools/testnet/roles/raiden/meta/main.yml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - keystore 3 | -------------------------------------------------------------------------------- /tools/testnet/roles/raiden/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: Raiden docker container 2 | docker_container: 3 | name: raiden 4 | state: started 5 | restart_policy: always 6 | pull: yes 7 | image: "{{ docker_repo_raiden }}" 8 | etc_hosts: 9 | logstash: "{{ hostvars[groups['role_infrastructure'][0]]['private_ip'] }}" 10 | hostname: "{{ hostname }}" 11 | ports: 12 | - 38647:38647/udp 13 | - 5001:5001 14 | volumes: 15 | - "{{ raiden_root }}:/root/.raiden" 16 | - "{{ keystore_root }}:/keystore" 17 | env: 18 | RAIDEN_LOGSTASH_HOST: logstash 19 | command: 20 | - "--eth-nodes" 21 | - "{% for item in groups['role_eth'] %}{{ hostvars[item]['private_ip'] }}{{ '' if loop.last else ',' }}{% endfor %}" 22 | - "--seed" 23 | - "{{ private_ip }}" 24 | - "--raiden-executable" 25 | - "{{ 'raiden_echo_node' if hostvars[inventory_hostname].get('tags.Echo') == 'true' else 'raiden' }}" 26 | - "--" 27 | - "--api-address" 28 | - "0.0.0.0:5001" 29 | - "--keystore-path" 30 | - "/keystore" 31 | - "--address" 32 | - "{{ keystore_address }}" 33 | - "--password-file" 34 | - "/keystore/password" 35 | - "--logging" 36 | - ":trace" 37 | - "--log-json" 38 | - "{{ '--token-address' if hostvars[inventory_hostname].get('tags.Echo') == 'true' else '' }}" 39 | - "{{ echo_node_token_address if hostvars[inventory_hostname].get('tags.Echo') == 'true' else '' }}" 40 | -------------------------------------------------------------------------------- /tools/testnet/roles/ssh_keys/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: Ensure SSH authorized_keys 2 | template: 3 | src: templates/authorized_keys.j2 4 | dest: "/home/{{ ansible_user }}/.ssh/authorized_keys" 5 | mode: 0600 6 | -------------------------------------------------------------------------------- /tools/testnet/roles/ssh_keys/templates/authorized_keys.j2: -------------------------------------------------------------------------------- 1 | {% for key in public_keys %}{{ key }} 2 | {% endfor %} 3 | -------------------------------------------------------------------------------- /tools/testnet/roles/traefik/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: Traefik config dir 2 | become: yes 3 | file: 4 | path: /etc/traefik 5 | state: directory 6 | 7 | - name: Traefik config file 8 | become: yes 9 | template: 10 | src: templates/traefik.toml.j2 11 | dest: /etc/traefik/traefik.toml 12 | 13 | - name: Traefik raiden proxy config 14 | become: yes 15 | template: 16 | src: templates/rules.toml.j2 17 | dest: /etc/traefik/rules.toml 18 | 19 | - name: Traefik docker container 20 | docker_container: 21 | name: traefik 22 | restart_policy: always 23 | pull: yes 24 | image: "{{ docker_repo_traefik }}" 25 | volumes: 26 | - "/var/run/docker.sock:/var/run/docker.sock" 27 | - "/etc/traefik:/etc/traefik" 28 | ports: 29 | - 80:80 30 | - 443:443 31 | - 8080:8080 32 | command: "-l DEBUG" 33 | -------------------------------------------------------------------------------- /tools/testnet/roles/traefik/templates/rules.toml.j2: -------------------------------------------------------------------------------- 1 | [backends] 2 | {% for node in groups['role_raiden'] %} 3 | [backends.be_{{ hostvars[node]['hostname'] }}] 4 | [backends.be_{{ hostvars[node]['hostname'] }}.servers.server1] 5 | url = "http://{{ hostvars[node]['private_ip'] }}:5001" 6 | {% endfor %} 7 | 8 | [frontends] 9 | {% for node in groups['role_raiden'] %} 10 | [frontends.fe_{{ hostvars[node]['hostname'] }}] 11 | backend = "be_{{ hostvars[node]['hostname'] }}" 12 | passHostHeader = true 13 | [frontends.fe_{{ hostvars[node]['hostname'] }}.routes.route1] 14 | rule = "Host:{{ hostvars[node]['hostname'].replace("_", "-") }}.{{ testnet_domain }}" 15 | entryPoints = "http" 16 | {% endfor %} 17 | -------------------------------------------------------------------------------- /tools/testnet/roles/traefik/templates/traefik.toml.j2: -------------------------------------------------------------------------------- 1 | defaultEntryPoints = ["http", "https"] 2 | 3 | [entryPoints] 4 | [entryPoints.http] 5 | address = ":80" 6 | [entryPoints.http.auth.basic] 7 | users = ["raiden:$apr1$xjPmLYWo$/LbcU0PHFRmWF3Q7.Jje4/"] 8 | [entryPoints.https] 9 | address = ":443" 10 | [entryPoints.https.tls] 11 | [entryPoints.https.auth.basic] 12 | users = ["raiden:$apr1$xjPmLYWo$/LbcU0PHFRmWF3Q7.Jje4/"] 13 | 14 | logLevel = "INFO" 15 | 16 | [acme] 17 | email = "ulrich@brainbot.com" 18 | storage = "/etc/traefik/acme.json" 19 | entrypoint = "https" 20 | OnDemand = true 21 | 22 | [docker] 23 | domain = "{{ testnet_domain }}" 24 | endpoint = "unix:///var/run/docker.sock" 25 | exposedbydefault = false 26 | watch = true 27 | 28 | [file] 29 | filename = "/etc/traefik/rules.toml" 30 | -------------------------------------------------------------------------------- /tools/testnet/roles/traefik/vars/main.yml: -------------------------------------------------------------------------------- 1 | docker_repo_traefik: "traefik:1.3.5" 2 | testnet_domain: "testnet.raiden.network" 3 | -------------------------------------------------------------------------------- /tools/testnet/variables.tf: -------------------------------------------------------------------------------- 1 | variable "project_name" { 2 | default = "raiden_testnet" 3 | } 4 | 5 | variable "keypair_name" { 6 | description = "AWS SSH key pair" 7 | default = "raiden-testnet" 8 | } 9 | 10 | variable "cidr_block" { 11 | default = "10.0.0.0/16" 12 | } 13 | 14 | variable "ami_name_filter" { 15 | default = "ubuntu/images/hvm-ssd/ubuntu-xenial-16.04-amd64-server-*" 16 | } 17 | 18 | variable "count_infrastructure" { 19 | default = 1 20 | } 21 | 22 | variable "count_eth" { 23 | default = 3 24 | } 25 | 26 | variable "count_raiden" { 27 | default = 100 28 | } 29 | 30 | variable "count_raiden_echo" { 31 | default = 1 32 | } 33 | 34 | variable "ip_offset" { 35 | type = "map" 36 | default = { 37 | "infrastructure" = 257, 38 | "eth" = 513, 39 | "raiden_echo" = 769, 40 | "raiden" = 1025 41 | } 42 | } 43 | 44 | variable "instance_type" { 45 | type = "map" 46 | default = { 47 | "infrastructure" = "t2.small", 48 | "eth" = "t2.small", 49 | "raiden_echo" = "t2.nano", 50 | "raiden" = "t2.nano" 51 | } 52 | } 53 | 54 | variable "volume_size" { 55 | type = "map" 56 | default = { 57 | "infrastructure" = 50, 58 | "eth" = 30, 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = coverage 3 | 4 | [testenv] 5 | deps = 6 | -rrequirements-dev.txt 7 | commands = 8 | coverage erase 9 | pytest --cov-append --exitfirst {posargs:./raiden/tests/unit ./raiden/tests/integration/api ./raiden/tests/integration} 10 | 11 | [testenv:flake8] 12 | deps = 13 | flake8 14 | commands= 15 | flake8 --exit-zero raiden/ tools/ 16 | 17 | [testenv:devenv] 18 | envdir = devenv 19 | basepython = python2.7 20 | usedevelop = True 21 | deps = 22 | -rrequirements-dev.txt 23 | commands = pytest --cov-append --exitfirst {posargs:./raiden/} 24 | 25 | [testenv:integration] 26 | commands = pytest --cov-append --initial-port=3000 --exitfirst ./raiden/tests/integration {posargs} 27 | 28 | [testenv:unit] 29 | commands = pytest --cov-append --initial-port=4000 --exitfirst ./raiden/tests/unit {posargs} 30 | 31 | [testenv:api] 32 | commands = pytest --cov-append --initial-port=5000 --exitfirst ./raiden/tests/integration/api {posargs} 33 | --------------------------------------------------------------------------------