├── .circleci ├── ci_increase_chart_version.sh ├── ci_publish.sh ├── config.yml ├── status.sh └── test_runner.py ├── .formatter.exs ├── .githooks └── pre-commit ├── .github ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── auto-merge-pr.yml │ ├── auto-pr-for-branch-syncing.yml │ └── enforce-changelog-labels.yml ├── .github_changelog_generator ├── .gitignore ├── .gitmodules ├── .releaserc.yaml ├── .tool-versions ├── AUTHORS ├── CHANGELOG.md ├── CODEOWNERS ├── Dockerfile.watcher ├── Dockerfile.watcher_info ├── LICENSE ├── Makefile ├── README.md ├── apps ├── omg_bus │ ├── lib │ │ ├── omg_bus.ex │ │ └── omg_bus │ │ │ ├── application.ex │ │ │ ├── event.ex │ │ │ ├── pubsub.ex │ │ │ └── supervisor.ex │ ├── mix.exs │ └── test │ │ ├── omg_bus │ │ └── event_test.exs │ │ └── test_helper.exs ├── omg_conformance │ ├── mix.exs │ └── test │ │ ├── omg_conformance │ │ └── conformance │ │ │ ├── merkle_proof_property_test.exs │ │ │ ├── merkle_proof_test.exs │ │ │ ├── signature_property_test.exs │ │ │ └── signature_test.exs │ │ ├── support │ │ └── conformance │ │ │ ├── merkle_proof_context.ex │ │ │ ├── merkle_proofs.ex │ │ │ ├── property.ex │ │ │ ├── signatures_hashes.ex │ │ │ └── signatures_hashes_case.ex │ │ └── test_helper.exs ├── omg_db │ ├── lib │ │ ├── db.ex │ │ └── omg_db │ │ │ ├── application.ex │ │ │ ├── measure.ex │ │ │ ├── models │ │ │ └── payment_exit_info.ex │ │ │ ├── release_tasks │ │ │ ├── init_key_value_db.ex │ │ │ ├── init_keys_with_values.ex │ │ │ └── set_key_value_db.ex │ │ │ ├── rocks_db.ex │ │ │ └── rocksdb │ │ │ ├── core.ex │ │ │ └── server.ex │ ├── mix.exs │ └── test │ │ ├── fixtures.exs │ │ ├── omg_db │ │ ├── application_test.exs │ │ ├── db_test.exs │ │ ├── models │ │ │ └── payment_exit_info_test.exs │ │ ├── release_tasks │ │ │ ├── init_key_value_db_test.exs │ │ │ ├── init_keys_with_values_test.exs │ │ │ └── set_key_value_db_test.exs │ │ └── rocks_db_test.exs │ │ ├── support │ │ └── rocks_db_case.ex │ │ └── test_helper.exs ├── omg_eth │ ├── lib │ │ ├── eth.ex │ │ └── omg_eth │ │ │ ├── application.ex │ │ │ ├── blockchain │ │ │ ├── bit_helper.ex │ │ │ ├── private_key.ex │ │ │ ├── transaction.ex │ │ │ └── transaction │ │ │ │ ├── hash.ex │ │ │ │ └── signature.ex │ │ │ ├── client.ex │ │ │ ├── configuration.ex │ │ │ ├── encoding.ex │ │ │ ├── encoding │ │ │ └── contract_constructor.ex │ │ │ ├── ethereum_height.ex │ │ │ ├── ethereum_height_monitor.ex │ │ │ ├── ethereum_height_monitor │ │ │ └── alarm_handler.ex │ │ │ ├── metric │ │ │ └── ethereumex.ex │ │ │ ├── release_tasks │ │ │ ├── set_contract.ex │ │ │ ├── set_ethereum_block_time.ex │ │ │ ├── set_ethereum_client.ex │ │ │ ├── set_ethereum_events_check_interval.ex │ │ │ └── set_ethereum_stalled_sync_threshold.ex │ │ │ ├── root_chain.ex │ │ │ ├── root_chain │ │ │ ├── abi.ex │ │ │ ├── abi_event_selector.ex │ │ │ ├── abi_function_selector.ex │ │ │ ├── event.ex │ │ │ ├── fields.ex │ │ │ ├── rpc.ex │ │ │ └── submit_block.ex │ │ │ ├── supervisor.ex │ │ │ └── transaction.ex │ ├── mix.exs │ └── test │ │ ├── fixtures.exs │ │ ├── omg_eth │ │ ├── application_test.exs │ │ ├── blockchain │ │ │ ├── bit_helper_test.exs │ │ │ ├── transaction │ │ │ │ ├── hash_test.exs │ │ │ │ └── signature_test.exs │ │ │ └── transaction_test.exs │ │ ├── client_test.exs │ │ ├── encoding │ │ │ └── contract_constructor_test.exs │ │ ├── encoding_test.exs │ │ ├── eth_test.exs │ │ ├── ethereum_height_monitor_test.exs │ │ ├── release_tasks │ │ │ ├── set_contract_test.exs │ │ │ ├── set_ethereum_block_time_test.exs │ │ │ ├── set_ethereum_client_test.exs │ │ │ ├── set_ethereum_events_check_interval_test.exs │ │ │ └── set_ethereum_stalled_sync_threshold_test.exs │ │ ├── root_chain │ │ │ ├── abi_test.exs │ │ │ └── event_test.exs │ │ └── root_chain_test.exs │ │ ├── support │ │ ├── defaults.ex │ │ ├── dev_geth.ex │ │ ├── dev_helper.ex │ │ ├── dev_node.ex │ │ ├── root_chain_helper.ex │ │ ├── snapshot_contracts.ex │ │ ├── token.ex │ │ ├── transaction_helper.ex │ │ └── wait_for.ex │ │ └── test_helper.exs ├── omg_status │ ├── .gitignore │ ├── README.md │ ├── lib │ │ ├── omg_status │ │ │ ├── alert │ │ │ │ ├── alarm.ex │ │ │ │ ├── alarm_handler.ex │ │ │ │ └── alarm_printer.ex │ │ │ ├── application.ex │ │ │ ├── configuration.ex │ │ │ ├── datadog_event │ │ │ │ ├── alarm_consumer.ex │ │ │ │ └── alarm_handler.ex │ │ │ ├── metric │ │ │ │ ├── datadog.ex │ │ │ │ ├── event.ex │ │ │ │ ├── statix.ex │ │ │ │ ├── telemetry.ex │ │ │ │ ├── tracer.ex │ │ │ │ └── vmstats_sink.ex │ │ │ ├── monitor │ │ │ │ ├── memory_monitor.ex │ │ │ │ └── statsd_monitor.ex │ │ │ ├── release_tasks │ │ │ │ ├── set_application.ex │ │ │ │ ├── set_logger.ex │ │ │ │ ├── set_sentry.ex │ │ │ │ └── set_tracer.ex │ │ │ └── sentry_filter.ex │ │ └── status.ex │ ├── mix.exs │ └── test │ │ ├── omg_status │ │ ├── alert │ │ │ └── alarm_printer_test.exs │ │ ├── datadog_event │ │ │ └── alarm_consumer_test.exs │ │ ├── integration │ │ │ └── alarms_test.exs │ │ ├── metric │ │ │ └── datadog_test.exs │ │ ├── monitor │ │ │ ├── memory_monitor_test.exs │ │ │ └── statsd_monitor_test.exs │ │ └── release_tasks │ │ │ ├── set_logger_test.exs │ │ │ ├── set_sentry_test.exs │ │ │ └── set_tracer_test.exs │ │ ├── sentry_filter_test.exs │ │ └── test_helper.exs ├── omg_utils │ ├── lib │ │ ├── omg_utils │ │ │ ├── app_version.ex │ │ │ ├── http_rpc │ │ │ │ ├── encoding.ex │ │ │ │ ├── error.ex │ │ │ │ ├── response.ex │ │ │ │ └── validators │ │ │ │ │ └── base.ex │ │ │ ├── paginator.ex │ │ │ └── remote_ip.ex │ │ └── utils.ex │ ├── mix.exs │ └── test │ │ ├── omg_utils │ │ ├── app_version_tet.exs │ │ ├── http_rpc │ │ │ ├── encoding_test.exs │ │ │ ├── response_test.exs │ │ │ └── validators │ │ │ │ └── base_test.exs │ │ └── remote_ip_test.exs │ │ └── test_helper.exs ├── omg_watcher │ ├── lib │ │ ├── omg_watcher.ex │ │ └── omg_watcher │ │ │ ├── api │ │ │ ├── account.ex │ │ │ ├── alarm.ex │ │ │ ├── configuration.ex │ │ │ ├── in_flight_exit.ex │ │ │ ├── status.ex │ │ │ ├── status_cache.ex │ │ │ ├── status_cache │ │ │ │ ├── external.ex │ │ │ │ └── storage.ex │ │ │ ├── transaction.ex │ │ │ └── utxo.ex │ │ │ ├── application.ex │ │ │ ├── block.ex │ │ │ ├── block_getter.ex │ │ │ ├── block_getter │ │ │ ├── block_application.ex │ │ │ ├── core.ex │ │ │ ├── measure.ex │ │ │ ├── status.ex │ │ │ └── supervisor.ex │ │ │ ├── block_validator.ex │ │ │ ├── child_manager.ex │ │ │ ├── configuration.ex │ │ │ ├── coordinator_setup.ex │ │ │ ├── crypto.ex │ │ │ ├── datadog_event │ │ │ ├── contract_event_consumer.ex │ │ │ └── encode.ex │ │ │ ├── ethereum_event_aggregator.ex │ │ │ ├── ethereum_event_listener.ex │ │ │ ├── ethereum_event_listener │ │ │ ├── core.ex │ │ │ └── measure.ex │ │ │ ├── event.ex │ │ │ ├── exit_processor.ex │ │ │ ├── exit_processor │ │ │ ├── canonicity.ex │ │ │ ├── competitor_info.ex │ │ │ ├── core.ex │ │ │ ├── double_spend.ex │ │ │ ├── exit_info.ex │ │ │ ├── finalizations.ex │ │ │ ├── in_flight_exit_info.ex │ │ │ ├── known_tx.ex │ │ │ ├── measure.ex │ │ │ ├── piggyback.ex │ │ │ ├── request.ex │ │ │ ├── standard_exit.ex │ │ │ ├── tools.ex │ │ │ └── tx_appendix.ex │ │ │ ├── fees.ex │ │ │ ├── fees │ │ │ └── fee_filter.ex │ │ │ ├── http_rpc │ │ │ ├── adapter.ex │ │ │ └── client.ex │ │ │ ├── merge_transaction_validator.ex │ │ │ ├── merkle.ex │ │ │ ├── monitor.ex │ │ │ ├── output.ex │ │ │ ├── raw_data.ex │ │ │ ├── release_tasks │ │ │ ├── set_application.ex │ │ │ ├── set_ethereum_events_check_interval.ex │ │ │ ├── set_exit_processor_sla_margin.ex │ │ │ └── set_tracer.ex │ │ │ ├── root_chain_coordinator.ex │ │ │ ├── root_chain_coordinator │ │ │ ├── core.ex │ │ │ ├── measure.ex │ │ │ └── service.ex │ │ │ ├── signature.ex │ │ │ ├── state.ex │ │ │ ├── state │ │ │ ├── core.ex │ │ │ ├── measure.ex │ │ │ ├── measurement_calculation.ex │ │ │ ├── transaction.ex │ │ │ ├── transaction │ │ │ │ ├── fee.ex │ │ │ │ ├── payment.ex │ │ │ │ ├── recovered.ex │ │ │ │ ├── signed.ex │ │ │ │ ├── validator.ex │ │ │ │ ├── validator │ │ │ │ │ ├── fee_claim.ex │ │ │ │ │ └── payment.ex │ │ │ │ └── witness.ex │ │ │ └── utxo_set.ex │ │ │ ├── supervisor.ex │ │ │ ├── sync_supervisor.ex │ │ │ ├── tracer.ex │ │ │ ├── typed_data_hash.ex │ │ │ ├── typed_data_hash │ │ │ ├── config.ex │ │ │ ├── tools.ex │ │ │ └── types.ex │ │ │ ├── utxo.ex │ │ │ ├── utxo │ │ │ └── position.ex │ │ │ ├── utxo_exit │ │ │ └── core.ex │ │ │ └── wire_format_types.ex │ ├── mix.exs │ └── test │ │ ├── fixtures.exs │ │ ├── omg_watcher │ │ ├── api │ │ │ ├── account_test.exs │ │ │ ├── alarm_test.exs │ │ │ └── status_cache_test.exs │ │ ├── block_getter │ │ │ └── core_test.exs │ │ ├── block_test.exs │ │ ├── block_validator_test.exs │ │ ├── child_manager_test.exs │ │ ├── crypto_test.exs │ │ ├── datadog_event │ │ │ ├── contract_event_consumer_test.exs │ │ │ └── encode_test.exs │ │ ├── ethereum_event_aggregator_test.exs │ │ ├── ethereum_event_listener │ │ │ └── core_test.exs │ │ ├── exit_processor │ │ │ ├── canonicity_test.exs │ │ │ ├── core │ │ │ │ └── state_interaction_test.exs │ │ │ ├── core_test.exs │ │ │ ├── exit_info_test.exs │ │ │ ├── finalizations_test.exs │ │ │ ├── in_flight_exit_info_test.exs │ │ │ ├── persistence_test.exs │ │ │ ├── piggyback_test.exs │ │ │ ├── standard_exit_test.exs │ │ │ └── tools_test.exs │ │ ├── fees │ │ │ └── fee_filter_test.exs │ │ ├── fees_test.exs │ │ ├── http_rpc │ │ │ └── adapter_test.exs │ │ ├── integration │ │ │ ├── block_getter_1_test.exs │ │ │ ├── block_getter_2_test.exs │ │ │ ├── block_getter_3_test.exs │ │ │ ├── block_getter_4_test.exs │ │ │ ├── block_getter_test.exs │ │ │ ├── in_flight_exit_test.exs │ │ │ ├── in_flight_exit_test_1_test.exs │ │ │ ├── in_flight_exit_test_2_test.exs │ │ │ ├── in_flight_exit_test_3_test.exs │ │ │ ├── in_flight_exit_test_4_test.exs │ │ │ ├── invalid_exit_1_test.exs │ │ │ ├── invalid_exit_2_test.exs │ │ │ ├── monitor_test.exs │ │ │ ├── root_chain_coordinator_test.exs │ │ │ └── test_server_test.exs │ │ ├── merge_transaction_validator_test.exs │ │ ├── merkle_test.exs │ │ ├── output_test.exs │ │ ├── raw_data_test.exs │ │ ├── release_tasks │ │ │ ├── set_ethereum_events_check_interval_test.exs │ │ │ ├── set_exit_processor_sla_margin_test.exs │ │ │ └── set_tracer_test.exs │ │ ├── root_chain_coordinator │ │ │ └── core_test.exs │ │ ├── signature_test.exs │ │ ├── state │ │ │ ├── core_test.exs │ │ │ ├── measurement_calculation_test.exs │ │ │ ├── persistence_test.exs │ │ │ ├── transaction │ │ │ │ ├── fee_test.exs │ │ │ │ ├── recovered_test.exs │ │ │ │ └── witness_test.exs │ │ │ ├── transaction_test.exs │ │ │ └── utxo_set_test.exs │ │ ├── state_test.exs │ │ ├── supervisor_test.exs │ │ ├── typed_data_hash_test.exs │ │ ├── utxo │ │ │ └── position_test.exs │ │ ├── utxo_exit │ │ │ └── core_test.exs │ │ ├── utxo_test.exs │ │ └── wire_format_types_test.exs │ │ ├── support │ │ ├── dev_crypto.ex │ │ ├── exit_processor │ │ │ ├── case.ex │ │ │ └── test_helper.ex │ │ ├── integration │ │ │ ├── bad_child_chain_server.ex │ │ │ ├── deposit_helper.ex │ │ │ ├── fixtures.exs │ │ │ ├── test_helper.ex │ │ │ └── test_server.ex │ │ ├── signature_helper.ex │ │ ├── test_helper.ex │ │ └── watcher_helper.ex │ │ └── test_helper.exs ├── omg_watcher_info │ ├── lib │ │ ├── omg_watcher_info │ │ │ ├── api │ │ │ │ ├── account.ex │ │ │ │ ├── block.ex │ │ │ │ ├── deposit.ex │ │ │ │ ├── stats.ex │ │ │ │ └── transaction.ex │ │ │ ├── application.ex │ │ │ ├── block_applicator.ex │ │ │ ├── db │ │ │ │ ├── block.ex │ │ │ │ ├── eth_event.ex │ │ │ │ ├── eth_event_txoutput.ex │ │ │ │ ├── repo.ex │ │ │ │ ├── transaction.ex │ │ │ │ ├── txoutput.ex │ │ │ │ └── types │ │ │ │ │ ├── atom_type.ex │ │ │ │ │ ├── block │ │ │ │ │ └── chunk.ex │ │ │ │ │ └── integer_type.ex │ │ │ ├── http_rpc │ │ │ │ ├── adapter.ex │ │ │ │ └── client.ex │ │ │ ├── measure.ex │ │ │ ├── order_fee_fetcher.ex │ │ │ ├── release_tasks │ │ │ │ ├── init_postgresql_db.ex │ │ │ │ └── set_tracer.ex │ │ │ ├── supervisor.ex │ │ │ ├── tracer.ex │ │ │ ├── transaction.ex │ │ │ └── utxo_selection.ex │ │ └── watcher_info.ex │ ├── mix.exs │ ├── priv │ │ └── repo │ │ │ └── migrations │ │ │ ├── 20180813131000_create_block_table.exs │ │ │ ├── 20180813131706_create_transaction_table.exs │ │ │ ├── 20180813133000_create_ethevent_table.exs │ │ │ ├── 20180813143343_create_txoutput_table.exs │ │ │ ├── 20190314105410_alter_transactions_table_add_metadata_field.exs │ │ │ ├── 20190315095855_alter_transactions_table_add_partitial_index.exs │ │ │ ├── 20190408131000_add_missing_indices_to_txoutputs.exs │ │ │ ├── 20190806111817_alter_txoutputs_ethevents_make_many_to_many_relation.exs │ │ │ ├── 20190917165912_set_inserted_at_updated_at_to_epoc.exs │ │ │ ├── 20200129051756_index_block_timestamp.exs │ │ │ ├── 20200211064454_add_txtype_to_transaction_and_output.exs │ │ │ ├── 20200214132000_add_and_fix_timestamps.exs │ │ │ ├── 20200514115919_add_eth_height_to_eth_events.exs │ │ │ └── 20200529085008_create_pending_block_table.exs │ └── test │ │ ├── fixtures.exs │ │ ├── omg_watcher_info │ │ ├── api │ │ │ ├── block_test.exs │ │ │ ├── deposit_test.exs │ │ │ ├── stats_test.exs │ │ │ └── transaction_test.exs │ │ ├── block_applicator_test.exs │ │ ├── db │ │ │ ├── block │ │ │ │ └── chunk_test.exs │ │ │ ├── block_test.exs │ │ │ ├── eth_event_test.exs │ │ │ ├── transaction_test.exs │ │ │ └── txoutput_test.exs │ │ ├── http_rpc │ │ │ └── adapter_test.exs │ │ ├── order_fee_fetcher_test.exs │ │ ├── release_tasks │ │ │ └── set_tracer_test.exs │ │ ├── transaction_test.exs │ │ └── utxo_selection_test.exs │ │ ├── support │ │ ├── factories │ │ │ ├── block_factory.ex │ │ │ ├── data_helper.ex │ │ │ ├── eth_event_factory.ex │ │ │ ├── transaction_factory.ex │ │ │ └── txoutput_factory.ex │ │ ├── factory.ex │ │ └── test_server.ex │ │ └── test_helper.exs ├── omg_watcher_rpc │ ├── lib │ │ ├── application.ex │ │ ├── configuration.ex │ │ ├── release_tasks │ │ │ ├── set_api_mode.ex │ │ │ ├── set_endpoint.ex │ │ │ └── set_tracer.ex │ │ ├── tracer.ex │ │ ├── web.ex │ │ └── web │ │ │ ├── controllers │ │ │ ├── account.ex │ │ │ ├── alarm.ex │ │ │ ├── block.ex │ │ │ ├── challenge.ex │ │ │ ├── configuration.ex │ │ │ ├── deposit.ex │ │ │ ├── fallback.ex │ │ │ ├── fee.ex │ │ │ ├── in_flight_exit.ex │ │ │ ├── stats.ex │ │ │ ├── status.ex │ │ │ ├── transaction.ex │ │ │ └── utxo.ex │ │ │ ├── endpoint.ex │ │ │ ├── plugs │ │ │ ├── health.ex │ │ │ ├── method_param_filter.ex │ │ │ └── supported_watcher_modes.ex │ │ │ ├── response.ex │ │ │ ├── router.ex │ │ │ ├── serializers │ │ │ └── base.ex │ │ │ ├── sockets │ │ │ └── socket.ex │ │ │ ├── validators │ │ │ ├── account_constraints.ex │ │ │ ├── block_constraints.ex │ │ │ ├── deposit_constraints.ex │ │ │ ├── helpers.ex │ │ │ ├── merge_constraints.ex │ │ │ ├── order.ex │ │ │ ├── transaction_constraints.ex │ │ │ └── typed_data_signed.ex │ │ │ └── views │ │ │ ├── account.ex │ │ │ ├── alarm.ex │ │ │ ├── block.ex │ │ │ ├── challenge.ex │ │ │ ├── configuration.ex │ │ │ ├── deposit.ex │ │ │ ├── error.ex │ │ │ ├── fee.ex │ │ │ ├── in_flight_exit.ex │ │ │ ├── stats.ex │ │ │ ├── status.ex │ │ │ ├── transaction.ex │ │ │ └── utxo.ex │ ├── mix.exs │ ├── priv │ │ └── swagger │ │ │ ├── info_api_specs.yaml │ │ │ ├── info_api_specs │ │ │ ├── account │ │ │ │ ├── paths.yaml │ │ │ │ ├── request_bodies.yaml │ │ │ │ ├── response_schemas.yaml │ │ │ │ ├── responses.yaml │ │ │ │ └── schemas.yaml │ │ │ ├── alarm │ │ │ │ ├── alarms_schema.yml │ │ │ │ ├── paths.yaml │ │ │ │ ├── response_schemas.yaml │ │ │ │ ├── responses.yaml │ │ │ │ └── schemas.yaml │ │ │ ├── batch_transaction │ │ │ │ ├── paths.yaml │ │ │ │ ├── request_bodies.yaml │ │ │ │ ├── response_schemas.yaml │ │ │ │ ├── responses.yaml │ │ │ │ └── schemas.yaml │ │ │ ├── block │ │ │ │ ├── paths.yaml │ │ │ │ ├── request_bodies.yaml │ │ │ │ ├── response_schemas.yaml │ │ │ │ ├── responses.yaml │ │ │ │ └── schemas.yaml │ │ │ ├── configuration │ │ │ │ ├── configuration_schema.yml │ │ │ │ ├── paths.yaml │ │ │ │ ├── response_schemas.yaml │ │ │ │ ├── responses.yaml │ │ │ │ └── schemas.yaml │ │ │ ├── deposit │ │ │ │ ├── paths.yaml │ │ │ │ ├── request_bodies.yaml │ │ │ │ ├── response_schemas.yaml │ │ │ │ ├── responses.yaml │ │ │ │ └── schemas.yaml │ │ │ ├── fees │ │ │ │ ├── paths.yaml │ │ │ │ ├── request_bodies.yaml │ │ │ │ ├── response_schemas.yaml │ │ │ │ ├── responses.yaml │ │ │ │ └── schemas.yaml │ │ │ ├── response_schemas.yaml │ │ │ ├── responses.yaml │ │ │ ├── stats │ │ │ │ ├── paths.yaml │ │ │ │ ├── response_schemas.yaml │ │ │ │ ├── responses.yaml │ │ │ │ └── schemas.yaml │ │ │ ├── swagger.yaml │ │ │ └── transaction │ │ │ │ ├── paths.yaml │ │ │ │ ├── request_bodies.yaml │ │ │ │ ├── response_schemas.yaml │ │ │ │ ├── responses.yaml │ │ │ │ └── schemas.yaml │ │ │ ├── security_critical_api_specs.yaml │ │ │ ├── security_critical_api_specs │ │ │ ├── account │ │ │ │ ├── paths.yaml │ │ │ │ ├── request_bodies.yaml │ │ │ │ ├── response_schemas.yaml │ │ │ │ ├── responses.yaml │ │ │ │ └── schemas.yaml │ │ │ ├── alarm │ │ │ │ ├── alarms_schema.yml │ │ │ │ ├── paths.yaml │ │ │ │ ├── response_schemas.yaml │ │ │ │ ├── responses.yaml │ │ │ │ └── schemas.yaml │ │ │ ├── batch_transaction │ │ │ │ ├── paths.yaml │ │ │ │ ├── request_bodies.yaml │ │ │ │ ├── response_schemas.yaml │ │ │ │ ├── responses.yaml │ │ │ │ └── schemas.yaml │ │ │ ├── block │ │ │ │ ├── paths.yaml │ │ │ │ ├── request_bodies.yaml │ │ │ │ ├── response_schemas.yaml │ │ │ │ ├── responses.yaml │ │ │ │ └── schemas.yaml │ │ │ ├── configuration │ │ │ │ ├── configuration_schema.yml │ │ │ │ ├── paths.yaml │ │ │ │ ├── response_schemas.yaml │ │ │ │ ├── responses.yaml │ │ │ │ └── schemas.yaml │ │ │ ├── in_flight_exit │ │ │ │ ├── paths.yaml │ │ │ │ ├── request_bodies.yaml │ │ │ │ ├── response_schemas.yaml │ │ │ │ ├── responses.yaml │ │ │ │ └── schemas.yaml │ │ │ ├── response_schemas.yaml │ │ │ ├── responses.yaml │ │ │ ├── status │ │ │ │ ├── byzantine_events_schema.yml │ │ │ │ ├── paths.yaml │ │ │ │ ├── request_bodies.yaml │ │ │ │ ├── response_schemas.yaml │ │ │ │ ├── responses.yaml │ │ │ │ └── schemas.yaml │ │ │ ├── swagger.yaml │ │ │ ├── transaction │ │ │ │ ├── paths.yaml │ │ │ │ ├── request_bodies.yaml │ │ │ │ ├── response_schemas.yaml │ │ │ │ ├── responses.yaml │ │ │ │ └── schemas.yaml │ │ │ └── utxo │ │ │ │ ├── paths.yaml │ │ │ │ ├── request_bodies.yaml │ │ │ │ ├── response_schemas.yaml │ │ │ │ ├── responses.yaml │ │ │ │ └── schemas.yaml │ │ │ ├── shared │ │ │ ├── paths.yaml │ │ │ ├── request_bodies.yaml │ │ │ └── schemas.yaml │ │ │ └── swagger.md │ └── test │ │ ├── omg_watcher_rpc │ │ ├── release_tasks │ │ │ ├── set_endpoint_test.exs │ │ │ └── set_tracer_test.exs │ │ ├── tracer_test.exs │ │ └── web │ │ │ ├── conn_case.ex │ │ │ ├── controllers │ │ │ ├── account_test.exs │ │ │ ├── alarm_test.exs │ │ │ ├── block_test.exs │ │ │ ├── challenge_test.exs │ │ │ ├── deposit_test.exs │ │ │ ├── enforce_content_plug_test.exs │ │ │ ├── fallback_test.exs │ │ │ ├── fee_test.exs │ │ │ ├── in_flight_exit_test.exs │ │ │ ├── stats_test.exs │ │ │ ├── status_test.exs │ │ │ ├── transaction_test.exs │ │ │ └── utxo_test.exs │ │ │ ├── data_case.ex │ │ │ ├── plugs │ │ │ ├── method_param_filter_test.exs │ │ │ └── supported_watcher_modes_test.exs │ │ │ ├── response_test.exs │ │ │ ├── router_test.exs │ │ │ ├── validators │ │ │ ├── account_contraints_test.exs │ │ │ ├── block_constraints_test.exs │ │ │ ├── merge_constraints_test.exs │ │ │ ├── transaction_constraints_test.exs │ │ │ └── typed_data_signed_test.exs │ │ │ ├── view_case.ex │ │ │ └── views │ │ │ └── transaction_test.exs │ │ └── test_helper.exs └── xomg_tasks │ ├── lib │ ├── mix │ │ └── tasks │ │ │ ├── watcher.ex │ │ │ └── watcher_info.ex │ └── utils.ex │ ├── mix.exs │ └── test │ └── test_helper.exs ├── bin ├── generate-localchain-env ├── revert ├── rocksdb ├── setup ├── variables └── variables_test_barebone ├── config ├── .credo.exs ├── config.exs ├── credo │ ├── license_header.ex │ └── require_parentheses_on_zero_arity_defs.ex ├── dev.exs ├── prod.exs ├── releases.exs └── test.exs ├── contract_addresses_template.env ├── coveralls.json ├── dialyzer.ignore-warnings ├── docker-compose-infura.yml ├── docker-compose-watcher.yml ├── docker-compose.datadog.yml ├── docker-compose.dev.yml ├── docker-compose.feefeed.yml ├── docker-compose.reorg.yml ├── docker-compose.specs.yml ├── docker-compose.yml ├── docker ├── create_databases.sql ├── geth │ ├── command │ └── geth-blank-password ├── nginx │ ├── geth_nginx.conf │ ├── nginx.conf │ └── nginx.reorg.conf └── static_feefeed │ └── file.json ├── docs ├── api_specs │ ├── errors.md │ ├── index.html.md │ └── status_events_specs.md ├── architecture.md ├── assets │ ├── OMG-network-eWallet.jpg │ ├── architecture_overview.jpg │ ├── dex_design │ │ ├── 01_ODEX Features.png │ │ ├── 02_Phase 1 - Technology Proof of Concept.png │ │ ├── 03_Phase 2 - MVP.png │ │ ├── 04_Phase 3 - Bonded Exchages.png │ │ ├── 05_Phase 4 - Order Privacy.png │ │ ├── 06_OMG On-chain Venue.png │ │ ├── 07_safety_considerations.png │ │ └── 08_ODEX Alternative State.png │ └── logo.png ├── branching.md ├── deployment_configuration.md ├── details.md ├── dex_design.md ├── exit_validation.md ├── fee_design.md ├── in_flight_exit_scenarios.md ├── install.md ├── morevp.md ├── perf_test_result_dumps.md ├── run_local_watcher.md ├── source_consumption_log.md ├── stack_architecture.md ├── standard_vs_in_flight_exits_interaction.md ├── tesuji_blockchain_design.md ├── transaction_validation.md ├── unified_api.md └── watcher_db_design.md ├── dummy ├── fees_setup.env ├── mix.exs ├── mix.lock ├── priv ├── dev-artifacts │ ├── README.md │ ├── fee_specs.dev.json │ └── fee_specs.test.json └── perf │ ├── .formatter.exs │ ├── .gitignore │ ├── Dockerfile │ ├── Makefile │ ├── README.md │ ├── apps │ └── load_test │ │ ├── .formatter.exs │ │ ├── .gitignore │ │ ├── README.md │ │ ├── lib │ │ ├── application.ex │ │ ├── child_chain │ │ │ ├── abi.ex │ │ │ ├── abi │ │ │ │ ├── abi_event_selector.ex │ │ │ │ ├── abi_function_selector.ex │ │ │ │ └── fields.ex │ │ │ ├── deposit.ex │ │ │ ├── exit.ex │ │ │ ├── transaction.ex │ │ │ ├── utxos.ex │ │ │ └── watcher_sync.ex │ │ ├── connection │ │ │ ├── child_chain.ex │ │ │ ├── connection_defaults.ex │ │ │ ├── watcher_info.ex │ │ │ └── watcher_security.ex │ │ ├── ethereum │ │ │ ├── account.ex │ │ │ ├── bit_helper.ex │ │ │ ├── crypto.ex │ │ │ ├── ethereum.ex │ │ │ ├── hash.ex │ │ │ ├── nonce_tracker.ex │ │ │ └── transaction │ │ │ │ ├── signature.ex │ │ │ │ └── transaction.ex │ │ ├── performance.ex │ │ ├── runner │ │ │ ├── childchain.ex │ │ │ ├── deposits.ex │ │ │ ├── smoke.ex │ │ │ ├── standard_exits.ex │ │ │ ├── transactions.ex │ │ │ ├── utxos_load.ex │ │ │ └── watcher_info.ex │ │ ├── scenario │ │ │ ├── account_transactions.ex │ │ │ ├── create_utxos.ex │ │ │ ├── deposits.ex │ │ │ ├── fund_account.ex │ │ │ ├── many_standard_exits.ex │ │ │ ├── smoke.ex │ │ │ ├── spend_eth_utxo.ex │ │ │ ├── start_standard_exit.ex │ │ │ ├── transactions.ex │ │ │ └── watcher_status.ex │ │ ├── service │ │ │ ├── datadog.ex │ │ │ ├── datadog │ │ │ │ ├── api.ex │ │ │ │ └── dummy_statix.ex │ │ │ ├── faucet.ex │ │ │ ├── metrics.ex │ │ │ ├── sleeper.ex │ │ │ └── sync.ex │ │ ├── test_runner.ex │ │ ├── test_runner │ │ │ ├── config.ex │ │ │ └── help.ex │ │ ├── utils │ │ │ └── encoding.ex │ │ └── watcher_info │ │ │ ├── balance.ex │ │ │ ├── client.ex │ │ │ ├── transaction.ex │ │ │ └── utxo.ex │ │ ├── mix.exs │ │ └── test │ │ ├── load_test │ │ ├── runner │ │ │ ├── childchain_test.exs │ │ │ ├── smoke_test.exs │ │ │ ├── standard_exit_test.exs │ │ │ ├── utxos_load_test.exs │ │ │ └── watcher_info_test.exs │ │ └── service │ │ │ └── datadog │ │ │ └── api_test.exs │ │ └── test_helper.exs │ ├── config │ ├── .credo.exs │ ├── config.exs │ ├── dev.exs │ ├── stress.exs │ └── test.exs │ ├── mix.exs │ ├── mix.lock │ └── scripts │ └── generate_api_client.sh ├── rel └── env.sh.eex ├── rootfs ├── watcher_entrypoint └── watcher_info_entrypoint ├── snapshot_reorg.env └── snapshots.env /.circleci/status.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | retries=0 4 | status=1 5 | 6 | # Retries roughly every 5 seconds up to 2 minutes 7 | while [ $retries -lt 24 ]; do 8 | alarms=$(make get-alarms) 9 | status=$? 10 | echo ${alarms} 11 | 12 | if [ "$status" -eq "0" ]; then 13 | exit 0 14 | fi 15 | 16 | retries=$(( ${retries} + 1 )) 17 | sleep 5 18 | done 19 | 20 | exit ${status} 21 | -------------------------------------------------------------------------------- /.formatter.exs: -------------------------------------------------------------------------------- 1 | # Used by "mix format" 2 | [ 3 | inputs: [ 4 | "config/*.exs", 5 | "rel/config.exs", 6 | "mix.exs", 7 | "apps/*/mix.exs", 8 | "apps/*/{lib,test,config}/**/*.{ex,exs}", 9 | "priv/*/config/config.exs", 10 | "priv/*/mix.exs", 11 | ] 12 | ++ (Path.wildcard("priv/*/apps/*/mix.exs") -- Enum.flat_map( 13 | ["priv/*/apps/watcher_info_api/mix.exs", "priv/*/apps/watcher_security_critical_api/mix.exs"], 14 | &Path.wildcard/1 15 | )) 16 | ++ (Path.wildcard("priv/*/apps/*/{lib,test,config}/**/*.{ex,exs}") -- (Path.wildcard("priv/*/apps/watcher_info_api/{lib,test,config}/**/*.{ex,exs}") ++ Path.wildcard("priv/*/apps/watcher_security_critical_api/{lib,test,config}/**/*.{ex,exs}"))), 17 | line_length: 120 18 | ] 19 | -------------------------------------------------------------------------------- /.githooks/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | echo "Is your code formatted?" 3 | exec mix format --check-formatted 4 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | :clipboard: Add associated issues, tickets, docs URL here. 2 | 3 | ## Overview 4 | 5 | Describe what your Pull Request is about in a few sentences. 6 | 7 | ## Changes 8 | 9 | Describe your changes and implementation choices. More details make PRs easier to review. 10 | 11 | - Change 1 12 | - Change 2 13 | - ... 14 | 15 | ## Testing 16 | 17 | Describe how to test your new feature/bug fix and if possible, a step by step guide on how to demo this. 18 | -------------------------------------------------------------------------------- /.github/workflows/auto-pr-for-branch-syncing.yml: -------------------------------------------------------------------------------- 1 | name: Auto PR for syncing master to master-v2 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | 7 | jobs: 8 | auto-pr-for-branch-syncing: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v2 12 | - name: Create Pull Request 13 | run: | 14 | set -o xtrace 15 | 16 | readonly FROM_BRANCH="master" 17 | readonly TO_BRANCH="master-v2" 18 | readonly TITLE="sync: auto syncing from ${FROM_BRANCH} to ${TO_BRANCH}" 19 | readonly BODY="Time to sync \`${TO_BRANCH}\` with updates from \`${FROM_BRANCH}\`!" 20 | 21 | curl -X POST "https://api.github.com/repos/omgnetwork/elixir-omg/pulls" \ 22 | -H "Accept: application/vnd.github.v3+json" \ 23 | -H "Authorization: token ${{ secrets.HOUSE_KEEPER_BOT_TOKEN }}" \ 24 | --data "{\"title\": \"${TITLE}\", \"head\": \"${FROM_BRANCH}\", \"base\": \"${TO_BRANCH}\", \"body\": \"${BODY}\"}" 25 | -------------------------------------------------------------------------------- /.github/workflows/enforce-changelog-labels.yml: -------------------------------------------------------------------------------- 1 | name: Enforce changelog labels 2 | 3 | on: 4 | pull_request: 5 | types: [opened, labeled, unlabeled, synchronize, reopened] 6 | branches: [master] 7 | 8 | jobs: 9 | enforce-changelog-label: 10 | runs-on: ubuntu-latest 11 | env: 12 | # When updating the labels here, also update the `configure-sections` of the `.github_changelog_generator` file 13 | ONE_OF_LABELS: "api|enhancement|breaking|bug|chore|documentation" 14 | steps: 15 | - name: Check the PR for a changelog label 16 | id: check-changelog-label 17 | run: | 18 | set -o xtrace 19 | # Using the issues API instead of pulls because it can return only the labels 20 | curl "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/issues/${{ github.event.pull_request.number }}/labels" \ 21 | | grep -o '"name": "[^"]*' \ 22 | | cut -d'"' -f4 \ 23 | | grep -E $ONE_OF_LABELS \ 24 | || (echo "::error::The PR is missing a valid changelog label. Label the PR with one of: ${ONE_OF_LABELS//|/, }." && exit 1) 25 | -------------------------------------------------------------------------------- /.github_changelog_generator: -------------------------------------------------------------------------------- 1 | # Issue/PR filter 2 | release-branch=master 3 | since-tag=v0.4.8 4 | exclude-tags-regex=.*-pre.* 5 | unreleased=true 6 | 7 | issues=false 8 | pull-requests=true 9 | pr-wo-labels=true 10 | 11 | # Categories 12 | pr-label=### Untagged pull requests 13 | 14 | # When updating the sections here, also update the `ONE_OF_LABELS` env vars in the `.github/workflows/enforce-changelog-labels.yml` file 15 | configure-sections={"api":{"prefix":"### API changes","labels":["api"]}, "breaking":{"prefix":"### Breaking changes","labels":["breaking"]}, "enhancement":{"prefix":"### Enhancements","labels":["enhancement"]}, "bug":{"prefix":"### Bug fixes","labels":["bug"]}, "chore":{"prefix":"### Chores","labels":["chore"]}, "documentation":{"prefix":"### Documentation updates","labels":["documentation"]}} 16 | 17 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "priv/cabbage"] 2 | path = priv/cabbage 3 | url = https://github.com/omgnetwork/specs.git 4 | branch = master 5 | 6 | -------------------------------------------------------------------------------- /.releaserc.yaml: -------------------------------------------------------------------------------- 1 | plugins: 2 | - - '@semantic-release/commit-analyzer' 3 | - preset: 'angular' 4 | releaseRules: 5 | - type: 'refactor' 6 | release: 'patch' 7 | - type: 'style' 8 | release: 'patch' 9 | - type: 'feat' 10 | release: 'patch' 11 | - type: 'chore' 12 | release: 'patch' 13 | - breaking: true 14 | release: 'minor' 15 | - '@semantic-release/release-notes-generator' 16 | - '@semantic-release/github' 17 | tagFormat: 'v${version}' 18 | dryRun: true 19 | # observing that job would not be running as it was considered as from PR branch 20 | # looks that unfortunately that is how it is designed: 21 | # https://github.com/semantic-release/semantic-release/issues/1166#issuecomment-500094323 22 | # this workaround is from: 23 | # https://github.com/semantic-release/semantic-release/issues/1074#issuecomment-696922883 24 | ci: false 25 | -------------------------------------------------------------------------------- /.tool-versions: -------------------------------------------------------------------------------- 1 | elixir 1.11.2 2 | erlang 23.1.4 3 | rust 1.46.0 4 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | OMG Network Pte Ltd 2 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | mix.lock @InoMurko 2 | -------------------------------------------------------------------------------- /apps/omg_bus/lib/omg_bus.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Bus do 16 | @moduledoc """ 17 | Modules purpose is to serve as a event bus, the implementation is in the `OMG.Bus.PubSub` macro. 18 | """ 19 | use OMG.Bus.PubSub 20 | end 21 | -------------------------------------------------------------------------------- /apps/omg_bus/lib/omg_bus/application.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Bus.Application do 16 | @moduledoc false 17 | 18 | use Application 19 | 20 | def start(_type, _args) do 21 | OMG.Bus.Supervisor.start_link() 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /apps/omg_bus/lib/omg_bus/event.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Bus.Event do 16 | @moduledoc """ 17 | Representation of a single event to be published on OMG event bus 18 | """ 19 | 20 | @enforce_keys [:topic, :event, :payload] 21 | @type topic_t() :: {atom(), binary()} | binary() 22 | @type t() :: %__MODULE__{topic: binary(), event: atom, payload: any()} 23 | 24 | defstruct [:topic, :event, :payload] 25 | 26 | @spec new(__MODULE__.topic_t(), atom(), any()) :: __MODULE__.t() 27 | def new({origin, topic}, event, payload) when is_atom(origin) and is_atom(event) do 28 | %__MODULE__{topic: "#{origin}:#{topic}", event: event, payload: payload} 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /apps/omg_bus/lib/omg_bus/supervisor.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Bus.Supervisor do 16 | @moduledoc """ 17 | OMG Bus top level supervisor. 18 | """ 19 | use Supervisor 20 | require Logger 21 | 22 | def start_link() do 23 | Supervisor.start_link(__MODULE__, :ok, name: __MODULE__) 24 | end 25 | 26 | def init(:ok) do 27 | children = [{OMG.Bus.PubSub, []}] 28 | 29 | opts = [strategy: :one_for_one] 30 | 31 | _ = Logger.info("Starting #{inspect(__MODULE__)}") 32 | Supervisor.init(children, opts) 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /apps/omg_bus/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule OMG.Bus.MixProject do 2 | use Mix.Project 3 | 4 | def project() do 5 | [ 6 | app: :omg_bus, 7 | version: version(), 8 | build_path: "../../_build", 9 | config_path: "../../config/config.exs", 10 | deps_path: "../../deps", 11 | lockfile: "../../mix.lock", 12 | elixir: "~> 1.8", 13 | elixirc_paths: elixirc_paths(Mix.env()), 14 | start_permanent: Mix.env() == :prod, 15 | deps: deps(), 16 | test_coverage: [tool: ExCoveralls] 17 | ] 18 | end 19 | 20 | def application() do 21 | [ 22 | mod: {OMG.Bus.Application, []}, 23 | extra_applications: [:logger], 24 | included_applications: [] 25 | ] 26 | end 27 | 28 | defp version() do 29 | "git" 30 | |> System.cmd(["describe", "--tags", "--abbrev=0"]) 31 | |> elem(0) 32 | |> String.replace("v", "") 33 | |> String.replace("\n", "") 34 | end 35 | 36 | # Specifies which paths to compile per environment. 37 | defp elixirc_paths(:prod), do: ["lib"] 38 | defp elixirc_paths(:dev), do: ["lib"] 39 | defp elixirc_paths(:test), do: ["lib", "test/support"] 40 | 41 | defp deps(), do: [{:phoenix_pubsub, "~> 2.0"}] 42 | end 43 | -------------------------------------------------------------------------------- /apps/omg_bus/test/omg_bus/event_test.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Bus.EventTest do 16 | @moduledoc false 17 | 18 | use ExUnit.Case 19 | 20 | alias OMG.Bus.Event 21 | 22 | test "creates a root chain event" do 23 | topic = "Deposit" 24 | event = :deposit 25 | payload = ["payload"] 26 | 27 | assert %Event{topic: "root_chain:" <> topic, event: event, payload: payload} == 28 | Event.new({:root_chain, topic}, event, payload) 29 | end 30 | 31 | test "creates a child chain event" do 32 | topic = "blocks" 33 | event = :deposit 34 | payload = ["payload"] 35 | 36 | assert %Event{topic: "child_chain:" <> topic, event: event, payload: payload} == 37 | Event.new({:child_chain, topic}, event, payload) 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /apps/omg_bus/test/test_helper.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | ExUnit.start() 15 | -------------------------------------------------------------------------------- /apps/omg_conformance/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule OMG.Conformance.MixProject do 2 | use Mix.Project 3 | 4 | def project() do 5 | [ 6 | app: :omg_conformance, 7 | version: version(), 8 | build_path: "../../_build", 9 | config_path: "../../config/config.exs", 10 | deps_path: "../../deps", 11 | lockfile: "../../mix.lock", 12 | elixir: "~> 1.8", 13 | elixirc_paths: elixirc_paths(Mix.env()), 14 | start_permanent: Mix.env() == :prod, 15 | deps: deps(), 16 | test_coverage: [tool: ExCoveralls] 17 | ] 18 | end 19 | 20 | def application() do 21 | [ 22 | extra_applications: [:logger] 23 | ] 24 | end 25 | 26 | defp version() do 27 | "git" 28 | |> System.cmd(["describe", "--tags", "--abbrev=0"]) 29 | |> elem(0) 30 | |> String.replace("v", "") 31 | |> String.replace("\n", "") 32 | end 33 | 34 | defp elixirc_paths(:prod), do: ["lib"] 35 | defp elixirc_paths(:dev), do: ["lib"] 36 | defp elixirc_paths(:test), do: ["lib", "test/support"] 37 | 38 | defp deps() do 39 | [ 40 | {:propcheck, "~> 1.1", only: [:test]}, 41 | {:omg_watcher, in_umbrella: true} 42 | ] 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /apps/omg_conformance/test/test_helper.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | ExUnit.configure(exclude: [integration: true, property: true]) 15 | {:ok, _} = Application.ensure_all_started(:propcheck) 16 | ExUnit.start() 17 | -------------------------------------------------------------------------------- /apps/omg_db/lib/omg_db/application.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.DB.Application do 16 | @moduledoc false 17 | 18 | use Application 19 | 20 | def start(_type, _args) do 21 | children = [OMG.DB.child_spec()] 22 | 23 | opts = [strategy: :one_for_one, name: OMG.DB.Supervisor] 24 | 25 | Supervisor.start_link(children, opts) 26 | end 27 | 28 | def start_phase(:attach_telemetry, :normal, _phase_args) do 29 | handlers = [["measure-db", OMG.DB.Measure.supported_events(), &OMG.DB.Measure.handle_event/4, nil]] 30 | 31 | Enum.each(handlers, fn handler -> 32 | case apply(:telemetry, :attach_many, handler) do 33 | :ok -> :ok 34 | {:error, :already_exists} -> :ok 35 | end 36 | end) 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /apps/omg_db/test/fixtures.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.DB.Fixtures do 16 | @moduledoc """ 17 | Contains fixtures for tests that require db 18 | """ 19 | use ExUnitFixtures.FixtureModule 20 | 21 | deffixture db_initialized do 22 | db_path = Briefly.create!(directory: true) 23 | Application.put_env(:omg_db, :path, db_path, persistent: true) 24 | 25 | :ok = OMG.DB.init(db_path) 26 | 27 | {:ok, started_apps} = Application.ensure_all_started(:omg_db) 28 | 29 | on_exit(fn -> 30 | Application.put_env(:omg_db, :path, nil) 31 | 32 | started_apps 33 | |> Enum.reverse() 34 | |> Enum.map(fn app -> :ok = Application.stop(app) end) 35 | end) 36 | 37 | :ok 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /apps/omg_db/test/omg_db/application_test.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.DB.ApplicationTest do 16 | @moduledoc """ 17 | Only tests if the application can start and stop and the db can init at some location 18 | """ 19 | use ExUnitFixtures 20 | use ExUnit.Case, async: false 21 | 22 | @moduletag :wrappers 23 | @moduletag :common 24 | 25 | @tag fixtures: [:db_initialized] 26 | test "starts and stops app, inits", %{db_initialized: db_result} do 27 | assert :ok = db_result 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /apps/omg_db/test/support/rocks_db_case.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.DB.RocksDBCase do 16 | @moduledoc """ 17 | Defines the useful common setup for all `...PersistenceTests`: 18 | - creates temp dir with `briefly` 19 | - initializes the low-level LevelDB storage and starts the test DB server 20 | """ 21 | 22 | use ExUnit.CaseTemplate 23 | alias OMG.DB.RocksDB.Server 24 | 25 | setup %{test: test_name} do 26 | {:ok, dir} = Briefly.create(directory: true) 27 | :ok = Server.init_storage(dir) 28 | name = :"TestDB_#{test_name}" 29 | {:ok, pid} = start_supervised(OMG.DB.child_spec(db_path: dir, name: name), restart: :temporary) 30 | {:ok, %{db_dir: dir, db_pid: pid, db_pid_name: name}} 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /apps/omg_db/test/test_helper.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | ExUnit.configure(exclude: [integration: true, property: true, wrappers: true]) 16 | ExUnitFixtures.start() 17 | ExUnitFixtures.load_fixture_files() 18 | ExUnit.start() 19 | 20 | {:ok, _} = Application.ensure_all_started(:briefly) 21 | -------------------------------------------------------------------------------- /apps/omg_eth/lib/omg_eth/metric/ethereumex.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Eth.Metric.Ethereumex do 16 | @moduledoc """ 17 | Telemetry handler for Ethereumex events 18 | """ 19 | alias OMG.Status.Metric.Datadog 20 | def supported_events(), do: [:ethereumex] 21 | 22 | def handle_event([:ethereumex], %{counter: counter}, %{method_name: method_name} = _metadata, _config) do 23 | Datadog.increment(method_name, counter) 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /apps/omg_eth/test/omg_eth/blockchain/bit_helper_test.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Eth.Blockchain.BitHelperTest do 16 | use ExUnit.Case, async: true 17 | doctest OMG.Eth.Blockchain.BitHelper 18 | end 19 | -------------------------------------------------------------------------------- /apps/omg_eth/test/omg_eth/blockchain/transaction/hash_test.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Eth.Blockchain.Transaction.HashTest do 16 | use ExUnit.Case, async: true 17 | doctest OMG.Eth.Blockchain.Transaction.Hash 18 | end 19 | -------------------------------------------------------------------------------- /apps/omg_eth/test/omg_eth/blockchain/transaction/signature_test.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Eth.Blockchain.Transaction.SignatureTest do 16 | use ExUnit.Case, async: true 17 | doctest OMG.Eth.Blockchain.Transaction.Signature 18 | end 19 | -------------------------------------------------------------------------------- /apps/omg_eth/test/omg_eth/blockchain/transaction_test.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Eth.Blockchain.TransactionTest do 16 | use ExUnit.Case, async: true 17 | doctest OMG.Eth.Blockchain.Transaction 18 | end 19 | -------------------------------------------------------------------------------- /apps/omg_eth/test/omg_eth/root_chain/event_test.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | defmodule OMG.RootChain.EventTest do 15 | use ExUnit.Case, async: true 16 | alias OMG.Eth.RootChain.Event 17 | 18 | test "that filter and building an event definition works as expected" do 19 | assert Event.get_events([:deposit_created]) == ["DepositCreated(address,uint256,address,uint256)"] 20 | end 21 | 22 | test "that order of returned events is preserved" do 23 | assert Event.get_events([:deposit_created, :in_flight_exit_challenged, :in_flight_exit_started]) == [ 24 | "DepositCreated(address,uint256,address,uint256)", 25 | "InFlightExitChallenged(address,bytes32,uint256)", 26 | "InFlightExitStarted(address,bytes32)" 27 | ] 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /apps/omg_eth/test/support/defaults.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Eth.Defaults do 16 | @moduledoc """ 17 | Internal defaults of non-production critical calls to `OMG.Eth.RootChain` and `OMG.Eth.Token`. 18 | 19 | Don't ever use this for `OMG.Eth.RootChain.submit_block/5` or any other production related code. 20 | Don't ever use this for `OMG.Eth.submit_block/5` or any other production related code. 21 | """ 22 | 23 | alias OMG.Eth.Encoding 24 | 25 | # safe, reasonable amount, equal to the testnet block gas limit 26 | @lots_of_gas 5_712_388 27 | @gas_price 1_000_000_000 28 | 29 | def tx_defaults() do 30 | Enum.map([value: 0, gasPrice: @gas_price, gas: @lots_of_gas], fn {k, v} -> {k, Encoding.to_hex(v)} end) 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /apps/omg_eth/test/support/dev_node.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule Support.DevNode do 16 | @moduledoc """ 17 | Common library for running geth and parity in dev mode. 18 | """ 19 | require Logger 20 | 21 | def start() do 22 | OMG.Eth.DevGeth.start() 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /apps/omg_eth/test/test_helper.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | ExUnit.configure(exclude: [integration: true, property: true, wrappers: true, common: true]) 16 | ExUnit.start() 17 | {:ok, _} = Application.ensure_all_started(:ethereumex) 18 | {:ok, _} = Application.ensure_all_started(:briefly) 19 | {:ok, _} = Application.ensure_all_started(:erlexec) 20 | -------------------------------------------------------------------------------- /apps/omg_status/.gitignore: -------------------------------------------------------------------------------- 1 | # The directory Mix will write compiled artifacts to. 2 | /_build 3 | 4 | # If you run "mix test --cover", coverage assets end up here. 5 | /cover 6 | 7 | # The directory Mix downloads your dependencies sources to. 8 | /deps 9 | 10 | # Where 3rd-party dependencies like ExDoc output generated docs. 11 | /doc 12 | 13 | # If the VM crashes, it generates a dump, let's ignore it too. 14 | erl_crash.dump 15 | 16 | # Also ignore archive artifacts (built via "mix archive.build"). 17 | *.ez 18 | -------------------------------------------------------------------------------- /apps/omg_status/README.md: -------------------------------------------------------------------------------- 1 | # Status 2 | Status is a umbrella application. Its purpose is to gather and send metrics. 3 | -------------------------------------------------------------------------------- /apps/omg_status/lib/omg_status/metric/tracer.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Status.Metric.Tracer do 16 | @moduledoc """ 17 | Trace requests and reports information to Datadog via Spandex 18 | """ 19 | 20 | use Spandex.Tracer, otp_app: :omg_status 21 | end 22 | -------------------------------------------------------------------------------- /apps/omg_status/lib/omg_status/release_tasks/set_application.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2019 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Status.ReleaseTasks.SetApplication do 16 | @moduledoc false 17 | @behaviour Config.Provider 18 | 19 | def init(args) do 20 | args 21 | end 22 | 23 | def load(config, release: release, current_version: current_version) do 24 | Config.Reader.merge(config, omg_status: [release: release, current_version: current_version]) 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /apps/omg_status/lib/omg_status/sentry_filter.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Status.SentryFilter do 16 | @moduledoc """ 17 | Sentry callback for filtering events. 18 | """ 19 | @behaviour Sentry.EventFilter 20 | 21 | # when the development environment restarts it lacks network access 22 | # something to do with Cloud DNS 23 | def exclude_exception?(%MatchError{term: {:error, :nxdomain}}, _), do: true 24 | 25 | # Ignoring 406 status code invalid headers exception 26 | def exclude_exception?(%Phoenix.NotAcceptableError{plug_status: 406}, _), do: true 27 | 28 | def exclude_exception?(%Plug.Parsers.RequestTooLargeError{}, _), do: true 29 | 30 | def exclude_exception?(%CaseClauseError{term: {:error, :econnrefused}}, _), do: true 31 | 32 | def exclude_exception?(_, _), do: false 33 | end 34 | -------------------------------------------------------------------------------- /apps/omg_status/test/sentry_filter_test.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Status.SentryFilterTest do 16 | use ExUnit.Case, async: true 17 | 18 | test "excludes exception properly" do 19 | # ignore excluded exception 20 | assert_raise( 21 | Phoenix.NotAcceptableError, 22 | fn -> 23 | raise Phoenix.NotAcceptableError, 24 | "Could not render \"406.json\" for OMG.WatcherRPC.Web.Views.Error, please define a matching clause for render/2 or define a template at \"lib/omg_watcher_rpc_web/templates/views/error/*\". No templates were compiled for this module." 25 | end 26 | ) 27 | 28 | assert Sentry.capture_exception( 29 | %Phoenix.NotAcceptableError{plug_status: 406}, 30 | event_source: :plug, 31 | result: :sync 32 | ) == :excluded 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /apps/omg_status/test/test_helper.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | ExUnit.configure(exclude: [integration: true, property: true, wrappers: true, common: true]) 16 | ExUnit.start() 17 | -------------------------------------------------------------------------------- /apps/omg_utils/lib/omg_utils/app_version.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Utils.AppVersion do 16 | @moduledoc false 17 | 18 | @sha String.replace(elem(System.cmd("git", ["rev-parse", "--short=7", "HEAD"]), 0), "\n", "") 19 | 20 | @doc """ 21 | Derive the running service's version for adding to a response. 22 | """ 23 | @spec version(Application.app()) :: String.t() 24 | def version(app) do 25 | {:ok, vsn} = :application.get_key(app, :vsn) 26 | List.to_string(vsn) <> "+" <> @sha 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /apps/omg_utils/lib/omg_utils/http_rpc/error.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Utils.HttpRPC.Error do 16 | @moduledoc """ 17 | Provides standard data structure for API Error response 18 | """ 19 | alias OMG.Utils.HttpRPC.Response 20 | 21 | @doc """ 22 | Serializes error's code and description provided in response's data field. 23 | """ 24 | @spec serialize(atom() | String.t(), String.t() | nil, map() | nil) :: map() 25 | def serialize(code, description, messages \\ nil) do 26 | %{ 27 | object: :error, 28 | code: code, 29 | description: description 30 | } 31 | |> add_messages(messages) 32 | |> Response.serialize() 33 | end 34 | 35 | defp add_messages(data, nil), do: data 36 | defp add_messages(data, messages), do: Map.put_new(data, :messages, messages) 37 | end 38 | -------------------------------------------------------------------------------- /apps/omg_utils/lib/utils.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Utils do 16 | @moduledoc false 17 | end 18 | -------------------------------------------------------------------------------- /apps/omg_utils/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule Utils.MixProject do 2 | use Mix.Project 3 | 4 | def project() do 5 | [ 6 | app: :omg_utils, 7 | version: version(), 8 | build_path: "../../_build", 9 | config_path: "../../config/config.exs", 10 | deps_path: "../../deps", 11 | lockfile: "../../mix.lock", 12 | elixir: "~> 1.8", 13 | elixirc_paths: elixirc_paths(Mix.env()), 14 | start_permanent: Mix.env() == :prod, 15 | deps: [], 16 | test_coverage: [tool: ExCoveralls] 17 | ] 18 | end 19 | 20 | def application() do 21 | [extra_applications: [:plug]] 22 | end 23 | 24 | defp version() do 25 | "git" 26 | |> System.cmd(["describe", "--tags", "--abbrev=0"]) 27 | |> elem(0) 28 | |> String.replace("v", "") 29 | |> String.replace("\n", "") 30 | end 31 | 32 | # Specifies which paths to compile per environment. 33 | defp elixirc_paths(:prod), do: ["lib"] 34 | defp elixirc_paths(:dev), do: ["lib"] 35 | defp elixirc_paths(:test), do: ["lib", "test/support"] 36 | end 37 | -------------------------------------------------------------------------------- /apps/omg_utils/test/omg_utils/app_version_tet.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Utils.AppVersionTest do 16 | use ExUnit.Case, async: true 17 | 18 | alias OMG.Utils.AppVersion 19 | 20 | describe "version/1" do 21 | test "returns a compliant semver when given an application" do 22 | # Using :elixir as the app because it is certain to be running during the test 23 | version = AppVersion.version(:elixir) 24 | assert {:ok, _} = Version.parse(version) 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /apps/omg_utils/test/omg_utils/http_rpc/encoding_test.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Utils.HttpRPC.EncodingTest do 16 | use ExUnit.Case, async: true 17 | 18 | alias OMG.Utils.HttpRPC.Encoding 19 | 20 | test "decodes all up/down/mixed case values" do 21 | assert [{:ok, <<222, 173, 190, 239>>}, {:ok, <<222, 173, 190, 239>>}, {:ok, <<222, 173, 190, 239>>}] == 22 | Enum.map(["0xdeadbeef", "0xDEADBEEF", "0xDeadBeeF"], &Encoding.from_hex/1) 23 | end 24 | 25 | test "doesn't decode hex without '0x' prefix" do 26 | assert {:error, :invalid_hex} == Encoding.from_hex("deadbeef") 27 | end 28 | 29 | test "encodes stuff" do 30 | assert "0xdeadbeef" == Encoding.to_hex(<<222, 173, 190, 239>>) 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /apps/omg_utils/test/test_helper.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | ExUnit.start() 16 | -------------------------------------------------------------------------------- /apps/omg_watcher/lib/omg_watcher.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Watcher do 16 | @moduledoc """ 17 | Watcher is responsible for syncing and validating the child chain, and providing a secure interface to it. 18 | 19 | For details see [here](README.md) and [here](docs/tesuji_blockchain_design.md) 20 | """ 21 | end 22 | -------------------------------------------------------------------------------- /apps/omg_watcher/lib/omg_watcher/api/alarm.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Watcher.API.Alarm do 16 | @moduledoc """ 17 | Watcher alarm API 18 | """ 19 | 20 | alias OMG.Status.Alert.Alarm 21 | 22 | @spec get_alarms() :: {:ok, Alarm.alarms()} 23 | def get_alarms(), do: {:ok, Alarm.all()} 24 | end 25 | -------------------------------------------------------------------------------- /apps/omg_watcher/lib/omg_watcher/api/configuration.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Watcher.API.Configuration do 16 | @moduledoc """ 17 | Watcher API for retrieving configuration 18 | """ 19 | 20 | alias OMG.Watcher.Configuration 21 | 22 | @spec get_configuration() :: {:ok, map()} 23 | def get_configuration() do 24 | configuration = %{ 25 | exit_processor_sla_margin: Configuration.exit_processor_sla_margin(), 26 | deposit_finality_margin: Configuration.deposit_finality_margin(), 27 | contract_semver: OMG.Eth.Configuration.contract_semver(), 28 | network: OMG.Eth.Configuration.network() 29 | } 30 | 31 | {:ok, configuration} 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /apps/omg_watcher/lib/omg_watcher/api/status.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Watcher.API.Status do 16 | @moduledoc """ 17 | Watcher status API 18 | """ 19 | 20 | alias OMG.Watcher.API.StatusCache 21 | 22 | @doc """ 23 | Returns status of the watcher from the ETS cache. 24 | """ 25 | @spec get_status() :: {:ok, StatusCache.status()} 26 | def get_status() do 27 | {:ok, StatusCache.get()} 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /apps/omg_watcher/lib/omg_watcher/api/status_cache/storage.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Watcher.API.StatusCache.Storage do 16 | @moduledoc """ 17 | Watcher status API storage 18 | """ 19 | 20 | @doc """ 21 | This gets periodically called (defined by Ethereum height change). 22 | """ 23 | def update_status(ets, key, eth_block_number, integration_module) do 24 | {:ok, status} = integration_module.get_status(eth_block_number) 25 | :ets.insert(ets, {key, status}) 26 | end 27 | 28 | def ensure_ets_init(status_cache) do 29 | case :ets.info(status_cache) do 30 | :undefined -> 31 | ^status_cache = :ets.new(status_cache, [:set, :public, :named_table, read_concurrency: true]) 32 | :ok 33 | 34 | _ -> 35 | :ok 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /apps/omg_watcher/lib/omg_watcher/block_getter/measure.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Watcher.BlockGetter.Measure do 16 | @moduledoc """ 17 | Counting business metrics sent to Datadog 18 | """ 19 | 20 | import OMG.Status.Metric.Event, only: [name: 1] 21 | 22 | alias OMG.Status.Metric.Datadog 23 | alias OMG.Watcher.BlockGetter 24 | 25 | @supported_events [[:process, BlockGetter]] 26 | def supported_events(), do: @supported_events 27 | 28 | def handle_event([:process, BlockGetter], _, _state, _config) do 29 | value = 30 | self() 31 | |> Process.info(:message_queue_len) 32 | |> elem(1) 33 | 34 | _ = Datadog.gauge(name(:block_getter_message_queue_len), value) 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /apps/omg_watcher/lib/omg_watcher/child_manager.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Watcher.ChildManager do 16 | @moduledoc """ 17 | Reports it's health to the Monitor after start or restart and shutsdown. 18 | """ 19 | use GenServer, restart: :transient 20 | 21 | require Logger 22 | @timer 100 23 | def start_link(args) do 24 | GenServer.start_link(__MODULE__, args, name: __MODULE__) 25 | end 26 | 27 | def init(args) do 28 | monitor = Keyword.fetch!(args, :monitor) 29 | {:ok, _tref} = :timer.send_after(@timer, :health_checkin) 30 | {:ok, %{timer: @timer, monitor: monitor}} 31 | end 32 | 33 | def handle_info(:health_checkin, state) do 34 | :ok = state.monitor.health_checkin() 35 | 36 | {:stop, :normal, state} 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /apps/omg_watcher/lib/omg_watcher/exit_processor/measure.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Watcher.ExitProcessor.Measure do 16 | @moduledoc """ 17 | Counting business metrics sent to Datadog 18 | """ 19 | 20 | import OMG.Status.Metric.Event, only: [name: 1] 21 | 22 | alias OMG.Status.Metric.Datadog 23 | alias OMG.Watcher.ExitProcessor 24 | 25 | def handle_event([:process, ExitProcessor], _, _state, _config) do 26 | value = 27 | self() 28 | |> Process.info(:message_queue_len) 29 | |> elem(1) 30 | 31 | _ = Datadog.gauge(name(:watcher_exit_processor_message_queue_len), value) 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /apps/omg_watcher/lib/omg_watcher/exit_processor/tx_appendix.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Watcher.ExitProcessor.TxAppendix do 16 | @moduledoc """ 17 | Part of the exit processor serving as the API to the transaction appendix 18 | 19 | Transaction appendix (TxAppendix) serves the transactions that were witnessed, but aren't included in the blocks 20 | """ 21 | 22 | alias OMG.Watcher.ExitProcessor 23 | 24 | @doc """ 25 | Enumerable of `Transaction.Signed.t()` 26 | """ 27 | @type t() :: Enumerable.t() 28 | 29 | @spec get_all(ExitProcessor.Core.t()) :: t() 30 | def get_all(%ExitProcessor.Core{in_flight_exits: ifes, competitors: competitors}) do 31 | ifes 32 | |> Map.values() 33 | |> Stream.concat(Map.values(competitors)) 34 | |> Stream.map(&Map.get(&1, :tx)) 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /apps/omg_watcher/lib/omg_watcher/release_tasks/set_application.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2019 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Watcher.ReleaseTasks.SetApplication do 16 | @moduledoc false 17 | @behaviour Config.Provider 18 | 19 | def init(args) do 20 | args 21 | end 22 | 23 | def load(config, release: release, current_version: current_version) do 24 | Config.Reader.merge(config, omg_watcher: [release: release, current_version: current_version]) 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /apps/omg_watcher/lib/omg_watcher/root_chain_coordinator/measure.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Watcher.RootChainCoordinator.Measure do 16 | @moduledoc """ 17 | Counting business metrics sent to Datadog 18 | """ 19 | 20 | import OMG.Status.Metric.Event, only: [name: 2] 21 | 22 | alias OMG.Status.Metric.Datadog 23 | alias OMG.Watcher.RootChainCoordinator 24 | 25 | def handle_event([:process, RootChainCoordinator], _, state, _config) do 26 | value = 27 | self() 28 | |> Process.info(:message_queue_len) 29 | |> elem(1) 30 | 31 | _ = Datadog.gauge(name(state.service_name, :message_queue_len), value) 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /apps/omg_watcher/lib/omg_watcher/root_chain_coordinator/service.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | defmodule OMG.Watcher.RootChainCoordinator.Service do 15 | @moduledoc """ 16 | Represents a state of a service that is coordinated by `RootChainCoordinator.Core` 17 | """ 18 | 19 | defstruct synced_height: nil, pid: nil 20 | 21 | @type t() :: %__MODULE__{ 22 | synced_height: pos_integer(), 23 | pid: pid() 24 | } 25 | end 26 | -------------------------------------------------------------------------------- /apps/omg_watcher/lib/omg_watcher/tracer.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Watcher.Tracer do 16 | @moduledoc """ 17 | Trace Ecto requests and reports information to Datadog via Spandex 18 | """ 19 | 20 | use Spandex.Tracer, otp_app: :omg_watcher 21 | end 22 | -------------------------------------------------------------------------------- /apps/omg_watcher/test/omg_watcher/http_rpc/adapter_test.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Watcher.HttpRPC.AdapterTest do 16 | use ExUnit.Case, async: true 17 | 18 | import FakeServer 19 | 20 | alias OMG.Utils.AppVersion 21 | alias OMG.Watcher.HttpRPC.Adapter 22 | 23 | describe "rpc_post/3" do 24 | test_with_server "includes X-Watcher-Version header" do 25 | route("/path", FakeServer.Response.ok()) 26 | _ = Adapter.rpc_post(%{}, "path", FakeServer.address()) 27 | 28 | expected_watcher_version = AppVersion.version(:omg_watcher_info) 29 | 30 | assert request_received( 31 | "/path", 32 | method: "POST", 33 | headers: %{"content-type" => "application/json", "x-watcher-version" => expected_watcher_version} 34 | ) 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /apps/omg_watcher/test/omg_watcher/state/transaction/witness_test.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Watcher.State.Transaction.WitnessTest do 16 | @moduledoc false 17 | 18 | use ExUnit.Case, async: true 19 | 20 | alias OMG.Watcher.State.Transaction.Witness 21 | 22 | describe "valid?/1" do 23 | test "returns true when is binary and 65 bytes long" do 24 | assert Witness.valid?(<<0::520>>) 25 | end 26 | 27 | test "returns false when not a binary" do 28 | refute Witness.valid?([<<0>>]) 29 | end 30 | 31 | test "returns false when not 65 bytes long" do 32 | refute Witness.valid?(<<0>>) 33 | end 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /apps/omg_watcher/test/omg_watcher/utxo/position_test.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.Watcher.Utxo.PositionTest do 16 | @moduledoc false 17 | 18 | use ExUnit.Case, async: true 19 | doctest OMG.Watcher.Utxo.Position 20 | end 21 | -------------------------------------------------------------------------------- /apps/omg_watcher/test/omg_watcher/utxo_test.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | defmodule OMG.Watcher.UtxoTest do 15 | @moduledoc false 16 | use ExUnit.Case, async: true 17 | doctest OMG.Watcher.Utxo 18 | end 19 | -------------------------------------------------------------------------------- /apps/omg_watcher/test/test_helper.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | ExUnit.configure( 16 | exclude: [mix_based_child_chain: true, watcher: true, common: true, integration: true, property: true, wrappers: true] 17 | ) 18 | 19 | ExUnitFixtures.load_fixture_files(Path.join([Mix.Project.build_path(), "../../", "apps/*/test/**/fixtures.exs"])) 20 | ExUnitFixtures.start() 21 | ExUnit.start() 22 | 23 | {:ok, _} = Application.ensure_all_started(:httpoison) 24 | {:ok, _} = Application.ensure_all_started(:fake_server) 25 | 26 | # TODO: even though watcher does not have postgres, this needs to be here 27 | # because tests breach scope 28 | Mix.Task.run("ecto.create", ~w(--quiet)) 29 | Mix.Task.run("ecto.migrate", ~w(--quiet)) 30 | 31 | {:ok, _} = Application.ensure_all_started(:briefly) 32 | {:ok, _} = Application.ensure_all_started(:erlexec) 33 | -------------------------------------------------------------------------------- /apps/omg_watcher_info/lib/omg_watcher_info/api/account.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.WatcherInfo.API.Account do 16 | @moduledoc """ 17 | Module provides operations related to plasma accounts. 18 | """ 19 | alias OMG.Utils.Paginator 20 | alias OMG.Watcher.Crypto 21 | alias OMG.WatcherInfo.DB 22 | 23 | @doc """ 24 | Returns a list of amounts of currencies that a given address owns 25 | """ 26 | @spec get_balance(Crypto.address_t()) :: list(DB.TxOutput.balance()) 27 | def get_balance(address) do 28 | DB.TxOutput.get_balance(address) 29 | end 30 | 31 | @doc """ 32 | Gets all utxos belonging to the given address. 33 | """ 34 | @spec get_utxos(Keyword.t()) :: Paginator.t(%DB.TxOutput{}) 35 | def get_utxos(params) do 36 | DB.TxOutput.get_utxos(params) 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /apps/omg_watcher_info/lib/omg_watcher_info/api/deposit.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.WatcherInfo.API.Deposit do 16 | @moduledoc """ 17 | Module provides operations related to deposits. 18 | """ 19 | 20 | alias OMG.Utils.Paginator 21 | alias OMG.WatcherInfo.DB 22 | 23 | @default_events_limit 100 24 | 25 | @doc """ 26 | Retrieves a list of deposits. 27 | Length of the list is limited by `limit` and `page` arguments. 28 | """ 29 | @spec get_deposits(Keyword.t()) :: Paginator.t(%DB.EthEvent{}) 30 | def get_deposits(constraints) do 31 | {:ok, address} = Keyword.fetch(constraints, :address) 32 | 33 | constraints 34 | |> Paginator.from_constraints(@default_events_limit) 35 | |> DB.EthEvent.get_deposits(address) 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /apps/omg_watcher_info/lib/omg_watcher_info/db/repo.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.WatcherInfo.DB.Repo do 16 | use Ecto.Repo, 17 | otp_app: :omg_watcher_info, 18 | adapter: Ecto.Adapters.Postgres 19 | end 20 | -------------------------------------------------------------------------------- /apps/omg_watcher_info/lib/omg_watcher_info/db/types/atom_type.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.WatcherInfo.DB.Types.AtomType do 16 | @moduledoc """ 17 | Custom Ecto type that converts DB's string value into atom. 18 | """ 19 | @behaviour Ecto.Type 20 | def type(), do: :string 21 | 22 | def cast(value), do: {:ok, value} 23 | 24 | def load(value), do: {:ok, String.to_existing_atom(value)} 25 | 26 | def dump(value) when is_atom(value), do: {:ok, Atom.to_string(value)} 27 | 28 | def dump(_), do: :error 29 | # https://hexdocs.pm/ecto/Ecto.Type.html#c:embed_as/1 30 | def embed_as(_), do: :self 31 | 32 | def equal?(value1, value2), do: value1 == value2 33 | end 34 | -------------------------------------------------------------------------------- /apps/omg_watcher_info/lib/omg_watcher_info/measure.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.WatcherInfo.Measure do 16 | @moduledoc """ 17 | Counting business metrics sent to Datadog. 18 | """ 19 | import OMG.Status.Metric.Event, only: [name: 1] 20 | 21 | alias OMG.Status.Metric.Datadog 22 | alias OMG.WatcherInfo.PendingBlockQueueLengthChecker 23 | 24 | @supported_events [ 25 | [:pending_block_queue_length, PendingBlockQueueLengthChecker] 26 | ] 27 | 28 | def supported_events(), do: @supported_events 29 | 30 | def handle_event([:pending_block_queue_length, PendingBlockQueueLengthChecker], %{length: length}, _state, _config) do 31 | _ = Datadog.gauge(name(:pending_block_queue_length), length) 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /apps/omg_watcher_info/lib/omg_watcher_info/release_tasks/init_postgresql_db.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2019 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.WatcherInfo.ReleaseTasks.InitPostgresqlDB do 16 | @moduledoc false 17 | @app :omg_watcher_info 18 | 19 | def migrate() do 20 | for repo <- repos() do 21 | {:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :up, all: true)) 22 | end 23 | end 24 | 25 | def rollback(repo, version) do 26 | {:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :down, to: version)) 27 | end 28 | 29 | defp repos() do 30 | _ = Application.load(@app) 31 | Application.fetch_env!(@app, :ecto_repos) 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /apps/omg_watcher_info/lib/omg_watcher_info/tracer.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.WatcherInfo.Tracer do 16 | @moduledoc """ 17 | Trace Ecto requests and reports information to Datadog via Spandex 18 | """ 19 | 20 | use Spandex.Tracer, otp_app: :omg_watcher_info 21 | end 22 | -------------------------------------------------------------------------------- /apps/omg_watcher_info/lib/watcher_info.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.WatcherInfo do 16 | @moduledoc """ 17 | WatcherInfo is responsible for the non-security-critical part of the Watcher. 18 | """ 19 | end 20 | -------------------------------------------------------------------------------- /apps/omg_watcher_info/priv/repo/migrations/20180813131000_create_block_table.exs: -------------------------------------------------------------------------------- 1 | defmodule OMG.WatcherInfo.Repo.Migrations.CreateBlockTable do 2 | use Ecto.Migration 3 | 4 | def change() do 5 | create table(:blocks, primary_key: false) do 6 | add :blknum, :bigint, null: false, primary_key: true 7 | add :hash, :binary, null: false 8 | add :timestamp, :integer, null: false 9 | add :eth_height, :bigint, null: false 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /apps/omg_watcher_info/priv/repo/migrations/20180813131706_create_transaction_table.exs: -------------------------------------------------------------------------------- 1 | defmodule OMG.WatcherInfo.Repo.Migrations.CreateTransactionTable do 2 | use Ecto.Migration 3 | 4 | def change() do 5 | create table(:transactions, primary_key: false) do 6 | add :txhash, :binary, primary_key: true 7 | add :txindex, :integer, null: false 8 | add :txbytes, :binary, null: false 9 | add :sent_at, :timestamp 10 | add :blknum, references(:blocks, column: :blknum, type: :bigint) 11 | end 12 | 13 | # TODO: this will work as long as there will be not nulls here 14 | create unique_index(:transactions, [:blknum, :txindex], name: :unq_transaction_blknum_txindex) 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /apps/omg_watcher_info/priv/repo/migrations/20180813133000_create_ethevent_table.exs: -------------------------------------------------------------------------------- 1 | defmodule OMG.WatcherInfo.Repo.Migrations.CreateEtheventTable do 2 | use Ecto.Migration 3 | 4 | def change() do 5 | create table(:ethevents, primary_key: false) do 6 | add :hash, :binary, primary_key: true 7 | add :blknum, :bigint 8 | add :txindex, :integer 9 | add :event_type, :string, size: 124, null: false 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /apps/omg_watcher_info/priv/repo/migrations/20180813143343_create_txoutput_table.exs: -------------------------------------------------------------------------------- 1 | defmodule OMG.WatcherInfo.Repo.Migrations.CreateTxoutputTable do 2 | use Ecto.Migration 3 | 4 | def change() do 5 | create table(:txoutputs, primary_key: false) do 6 | add :blknum, :bigint, null: false, primary_key: true 7 | add :txindex, :integer, null: false, primary_key: true 8 | add :oindex, :integer, null: false, primary_key: true 9 | add :creating_txhash, references(:transactions, column: :txhash, type: :binary) 10 | add :creating_deposit, references(:ethevents, column: :hash, type: :binary) 11 | add :spending_txhash, references(:transactions, column: :txhash, type: :binary) 12 | add :spending_exit, references(:ethevents, column: :hash, type: :binary) 13 | add :spending_tx_oindex, :integer 14 | add :owner, :binary, null: false 15 | add :amount, :decimal, precision: 81, scale: 0, null: false 16 | add :currency, :binary, null: false 17 | add :proof, :binary 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /apps/omg_watcher_info/priv/repo/migrations/20190314105410_alter_transactions_table_add_metadata_field.exs: -------------------------------------------------------------------------------- 1 | defmodule OMG.WatcherInfo.DB.Repo.Migrations.AlterTransactionsTableAddMetadataField do 2 | use Ecto.Migration 3 | 4 | def change() do 5 | alter table(:transactions) do 6 | add(:metadata, :binary) 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /apps/omg_watcher_info/priv/repo/migrations/20190315095855_alter_transactions_table_add_partitial_index.exs: -------------------------------------------------------------------------------- 1 | defmodule OMG.WatcherInfo.DB.Repo.Migrations.AlterTransactionsTableAddPartialIndex do 2 | use Ecto.Migration 3 | 4 | def up() do 5 | execute("CREATE INDEX transactions_metadata_index ON transactions(metadata) WHERE metadata IS NOT NULL") 6 | end 7 | 8 | def down() do 9 | execute("DROP INDEX transactions_metadata_index") 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /apps/omg_watcher_info/priv/repo/migrations/20190408131000_add_missing_indices_to_txoutputs.exs: -------------------------------------------------------------------------------- 1 | defmodule OMG.WatcherInfo.Repo.Migrations.AddMissingIndicesToTxOuputs do 2 | use Ecto.Migration 3 | 4 | def change() do 5 | create index(:txoutputs, [:creating_txhash, :spending_txhash]) 6 | create index(:txoutputs, [:creating_deposit]) 7 | create index(:txoutputs, [:spending_txhash]) 8 | create index(:txoutputs, [:spending_exit], where: "spending_exit IS NOT NULL") 9 | create index(:txoutputs, [:owner]) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /apps/omg_watcher_info/priv/repo/migrations/20190917165912_set_inserted_at_updated_at_to_epoc.exs: -------------------------------------------------------------------------------- 1 | defmodule OMG.WatcherInfo.Repo.Migrations.SetInsertedAtUpdatedAtToEpoch do 2 | use Ecto.Migration 3 | 4 | def change() do 5 | execute("UPDATE txoutputs SET inserted_at = 'epoch' at time zone 'utc';") 6 | execute("UPDATE txoutputs SET updated_at = 'epoch' at time zone 'utc';") 7 | execute("ALTER TABLE txoutputs ALTER COLUMN inserted_at SET NOT NULL;") 8 | execute("ALTER TABLE txoutputs ALTER COLUMN updated_at SET NOT NULL;") 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /apps/omg_watcher_info/priv/repo/migrations/20200129051756_index_block_timestamp.exs: -------------------------------------------------------------------------------- 1 | defmodule OMG.WatcherInfo.DB.Repo.Migrations.IndexBlockTimestamp do 2 | use Ecto.Migration 3 | 4 | def change() do 5 | create(index(:blocks, [:timestamp])) 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /apps/omg_watcher_info/priv/repo/migrations/20200514115919_add_eth_height_to_eth_events.exs: -------------------------------------------------------------------------------- 1 | defmodule OMG.WatcherInfo.DB.Repo.Migrations.AddEthHeightToEthEvents do 2 | use Ecto.Migration 3 | 4 | def up() do 5 | alter table(:ethevents) do 6 | add(:eth_height, :integer) 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /apps/omg_watcher_info/priv/repo/migrations/20200529085008_create_pending_block_table.exs: -------------------------------------------------------------------------------- 1 | defmodule OMG.WatcherInfo.DB.Repo.Migrations.CreatePendingBlockTable do 2 | use Ecto.Migration 3 | 4 | def change() do 5 | create table(:pending_blocks, primary_key: false) do 6 | add :blknum, :bigint, null: false, primary_key: true 7 | add :data, :binary, null: false 8 | 9 | timestamps([type: :timestamptz, default: fragment("('epoch'::TIMESTAMPTZ AT TIME ZONE 'UTC')")]) 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /apps/omg_watcher_info/test/test_helper.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | ExUnit.configure(exclude: [mix_based_child_chain: true, integration: true, property: true, wrappers: true]) 16 | ExUnitFixtures.start() 17 | ExUnit.start() 18 | 19 | {:ok, _} = Application.ensure_all_started(:httpoison) 20 | {:ok, _} = Application.ensure_all_started(:fake_server) 21 | {:ok, _} = Application.ensure_all_started(:briefly) 22 | {:ok, _} = Application.ensure_all_started(:erlexec) 23 | {:ok, _} = Application.ensure_all_started(:ex_machina) 24 | 25 | Mix.Task.run("ecto.create", ~w(--quiet)) 26 | Mix.Task.run("ecto.migrate", ~w(--quiet)) 27 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/lib/configuration.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.WatcherRPC.Configuration do 16 | @moduledoc """ 17 | Provides access to applications configuration 18 | """ 19 | @app :omg_watcher_rpc 20 | 21 | @spec version() :: String.t() 22 | def version() do 23 | OMG.Utils.AppVersion.version(@app) 24 | end 25 | 26 | @spec service_name() :: atom() 27 | def service_name() do 28 | Application.get_env(@app, :api_mode) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/lib/release_tasks/set_api_mode.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2019 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.WatcherRPC.ReleaseTasks.SetApiMode do 16 | @moduledoc false 17 | @behaviour Config.Provider 18 | require Logger 19 | 20 | def init(nil) do 21 | exit("WatcherRPC's API mode is not provided.") 22 | end 23 | 24 | def init(args) do 25 | args 26 | end 27 | 28 | def load(config, api_mode) do 29 | Config.Reader.merge(config, omg_watcher_rpc: [api_mode: api_mode]) 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/lib/web/controllers/alarm.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.WatcherRPC.Web.Controller.Alarm do 16 | @moduledoc """ 17 | Module provides operation related to the watcher raised alarms that might point to 18 | faulty watcher node. 19 | """ 20 | 21 | use OMG.WatcherRPC.Web, :controller 22 | 23 | alias OMG.Watcher.API.Alarm 24 | 25 | def get_alarms(conn, _params) do 26 | {:ok, alarms} = Alarm.get_alarms() 27 | api_response(alarms, conn, :alarm) 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/lib/web/controllers/challenge.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.WatcherRPC.Web.Controller.Challenge do 16 | @moduledoc """ 17 | Handles exit challenges 18 | """ 19 | 20 | use OMG.WatcherRPC.Web, :controller 21 | 22 | alias OMG.Watcher.API 23 | alias OMG.Watcher.Utxo 24 | 25 | @doc """ 26 | Challenges exits 27 | """ 28 | def get_utxo_challenge(conn, params) do 29 | with {:ok, utxo_pos} <- expect(params, "utxo_pos", :pos_integer), 30 | {:ok, utxo} <- Utxo.Position.decode(utxo_pos) do 31 | utxo 32 | |> API.Utxo.create_challenge() 33 | |> api_response(conn, :challenge) 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/lib/web/controllers/configuration.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.WatcherRPC.Web.Controller.Configuration do 16 | @moduledoc """ 17 | Module provides operation related to the watcher raised alarms that might point to 18 | faulty watcher node. 19 | """ 20 | 21 | use OMG.WatcherRPC.Web, :controller 22 | 23 | alias OMG.Watcher.API.Configuration 24 | 25 | def get_configuration(conn, _params) do 26 | {:ok, configuration} = Configuration.get_configuration() 27 | api_response(configuration, conn, :configuration) 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/lib/web/controllers/deposit.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.WatcherRPC.Web.Controller.Deposit do 16 | @moduledoc """ 17 | Operations related to deposits. 18 | """ 19 | 20 | use OMG.WatcherRPC.Web, :controller 21 | 22 | alias OMG.WatcherInfo.API.Deposit, as: InfoApiDeposit 23 | alias OMG.WatcherRPC.Web.Validator 24 | 25 | @doc """ 26 | Retrieves a list of deposits. 27 | """ 28 | def get_deposits(conn, params) do 29 | case Validator.DepositConstraints.parse(params) do 30 | {:ok, constraints} -> 31 | constraints 32 | |> InfoApiDeposit.get_deposits() 33 | |> api_response(conn, :deposits) 34 | 35 | error -> 36 | error 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/lib/web/controllers/stats.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.WatcherRPC.Web.Controller.Stats do 16 | @moduledoc """ 17 | Operations related to network statistics. 18 | """ 19 | 20 | use OMG.WatcherRPC.Web, :controller 21 | 22 | alias OMG.WatcherInfo.API.Stats, as: InfoApiStats 23 | 24 | @doc """ 25 | Retrieves network statistics 26 | """ 27 | def get_statistics(conn, _params) do 28 | response = InfoApiStats.get() 29 | api_response(response, conn, :stats) 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/lib/web/controllers/status.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.WatcherRPC.Web.Controller.Status do 16 | @moduledoc """ 17 | Module provides operation related to the child chain health status, like: geth syncing status, last minned block 18 | number and time and last block verified by watcher. 19 | """ 20 | 21 | use OMG.WatcherRPC.Web, :controller 22 | # check for health before calling action 23 | plug(OMG.WatcherRPC.Web.Plugs.Health) 24 | alias OMG.Watcher.API.Status 25 | 26 | @doc """ 27 | Gets plasma network and Watcher status 28 | """ 29 | def get_status(conn, _params) do 30 | api_response(Status.get_status(), conn, :status) 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/lib/web/controllers/utxo.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.WatcherRPC.Web.Controller.Utxo do 16 | @moduledoc """ 17 | Operations related to utxo. 18 | Modify the state in the database. 19 | """ 20 | 21 | use OMG.WatcherRPC.Web, :controller 22 | 23 | alias OMG.Watcher.API 24 | alias OMG.Watcher.Utxo 25 | 26 | def get_utxo_exit(conn, params) do 27 | with {:ok, utxo_pos} <- expect(params, "utxo_pos", :pos_integer), 28 | {:ok, utxo} <- Utxo.Position.decode(utxo_pos) do 29 | utxo 30 | |> API.Utxo.compose_utxo_exit() 31 | |> api_response(conn, :utxo_exit) 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/lib/web/response.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.WatcherRPC.Web.Response do 16 | @moduledoc """ 17 | Prepares the response into the expected result/data format. 18 | 19 | Contains only the behaviours specific to the watcher. 20 | For the generic response, see `OMG.Utils.HttpRPC.Response`. 21 | """ 22 | 23 | alias OMG.WatcherRPC.Configuration 24 | 25 | @doc """ 26 | Adds "version" and "service_name" to the response map. 27 | """ 28 | @spec add_app_infos(map()) :: %{version: String.t(), service_name: String.t()} 29 | def add_app_infos(response) do 30 | response 31 | |> Map.put(:version, Configuration.version()) 32 | |> Map.put(:service_name, "#{Configuration.service_name()}") 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/lib/web/serializers/base.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.WatcherRPC.Web.Serializer.Base do 16 | @moduledoc """ 17 | Common structure formatters module. 18 | """ 19 | 20 | def to_utxo(%{blknum: blknum, txindex: txindex, oindex: oindex} = db_entry) do 21 | alias OMG.Watcher.Utxo 22 | require Utxo 23 | 24 | db_entry 25 | |> Map.take([ 26 | :amount, 27 | :currency, 28 | :blknum, 29 | :txindex, 30 | :oindex, 31 | :otype, 32 | :owner, 33 | :creating_txhash, 34 | :spending_txhash, 35 | :inserted_at, 36 | :updated_at 37 | ]) 38 | |> Map.put(:utxo_pos, Utxo.position(blknum, txindex, oindex) |> Utxo.Position.encode()) 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/lib/web/validators/account_constraints.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.WatcherRPC.Web.Validator.AccountConstraints do 16 | @moduledoc """ 17 | Validates `/account.get_utxos` query parameters 18 | """ 19 | 20 | alias OMG.WatcherRPC.Web.Validator.Helpers 21 | 22 | @doc """ 23 | Validates possible query constraints, stops on first error. 24 | """ 25 | @spec parse(%{binary() => any()}) :: {:ok, Keyword.t()} | {:error, any()} 26 | def parse(params) do 27 | constraints = [ 28 | {"limit", [pos_integer: true, lesser: 1000, optional: true], :limit}, 29 | {"page", [:pos_integer, :optional], :page}, 30 | {"address", [:address], :address} 31 | ] 32 | 33 | Helpers.validate_constraints(params, constraints) 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/lib/web/validators/deposit_constraints.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.WatcherRPC.Web.Validator.DepositConstraints do 16 | @moduledoc """ 17 | Validates query parameters for `deposit.all` 18 | """ 19 | 20 | alias OMG.WatcherRPC.Web.Validator.Helpers 21 | 22 | @doc """ 23 | Validates possible query constraints, stops on first error. 24 | """ 25 | @spec parse(%{binary() => any()}) :: {:ok, Keyword.t()} | {:error, any()} 26 | def parse(params) do 27 | constraints = [ 28 | {"limit", [pos_integer: true, lesser: 1000, optional: true], :limit}, 29 | {"page", [:pos_integer, :optional], :page}, 30 | {"address", :address, :address} 31 | ] 32 | 33 | Helpers.validate_constraints(params, constraints) 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/lib/web/views/alarm.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.WatcherRPC.Web.View.Alarm do 16 | @moduledoc """ 17 | The alarm view for rendering json 18 | """ 19 | 20 | use OMG.WatcherRPC.Web, :view 21 | alias OMG.Utils.HttpRPC.Response 22 | alias OMG.WatcherRPC.Web.Response, as: WatcherRPCResponse 23 | 24 | def render("alarm.json", %{response: alarms}) do 25 | alarms 26 | |> Response.serialize() 27 | |> WatcherRPCResponse.add_app_infos() 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/lib/web/views/challenge.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.WatcherRPC.Web.View.Challenge do 16 | @moduledoc """ 17 | The challenge view for rendering json 18 | """ 19 | 20 | use OMG.WatcherRPC.Web, :view 21 | alias OMG.Utils.HttpRPC.Response 22 | alias OMG.WatcherRPC.Web.Response, as: WatcherRPCResponse 23 | 24 | def render("challenge.json", %{response: challenge}) do 25 | challenge 26 | |> Response.serialize() 27 | |> WatcherRPCResponse.add_app_infos() 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/lib/web/views/configuration.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.WatcherRPC.Web.View.Configuration do 16 | @moduledoc """ 17 | The Configuration view for rendering json 18 | """ 19 | 20 | use OMG.WatcherRPC.Web, :view 21 | alias OMG.Utils.HttpRPC.Response 22 | alias OMG.WatcherRPC.Web.Response, as: WatcherRPCResponse 23 | 24 | def render("configuration.json", %{response: configuration}) do 25 | configuration 26 | |> to_api_format() 27 | |> Response.serialize() 28 | |> WatcherRPCResponse.add_app_infos() 29 | end 30 | 31 | defp to_api_format(%{contract_semver: contract_semver, network: network} = response) do 32 | response 33 | |> Map.put(:contract_semver, {:skip_hex_encode, contract_semver}) 34 | |> Map.put(:network, {:skip_hex_encode, network}) 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/lib/web/views/stats.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.WatcherRPC.Web.View.Stats do 16 | @moduledoc """ 17 | The block view for rendering json 18 | """ 19 | 20 | use OMG.WatcherRPC.Web, :view 21 | 22 | alias OMG.Utils.HttpRPC.Response 23 | alias OMG.WatcherRPC.Web.Response, as: WatcherRPCResponse 24 | 25 | def render("stats.json", %{response: stats}) do 26 | stats 27 | |> Response.serialize() 28 | |> WatcherRPCResponse.add_app_infos() 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/lib/web/views/utxo.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.WatcherRPC.Web.View.Utxo do 16 | @moduledoc """ 17 | The utxo view for rendering json 18 | """ 19 | 20 | use OMG.WatcherRPC.Web, :view 21 | alias OMG.Utils.HttpRPC.Response 22 | alias OMG.WatcherRPC.Web.Response, as: WatcherRPCResponse 23 | 24 | def render("utxo_exit.json", %{response: utxo_exit}) do 25 | utxo_exit 26 | |> Response.serialize() 27 | |> WatcherRPCResponse.add_app_infos() 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/account/request_bodies.yaml: -------------------------------------------------------------------------------- 1 | AddressBodySchema: 2 | description: HEX-encoded address of the account and pagination fields 3 | required: true 4 | content: 5 | application/json: 6 | schema: 7 | title: 'AddressBodySchema' 8 | type: object 9 | properties: 10 | address: 11 | type: string 12 | page: 13 | type: integer 14 | format: int32 15 | default: 1 16 | limit: 17 | type: integer 18 | format: int32 19 | default: 200 20 | 21 | required: 22 | - address 23 | example: 24 | address: '0xb3256026863eb6ae5b06fa396ab09069784ea8ea' 25 | limit: 100 26 | page: 2 27 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/account/responses.yaml: -------------------------------------------------------------------------------- 1 | AccountBalanceResponse: 2 | description: Account balance successful response 3 | content: 4 | application/json: 5 | schema: 6 | $ref: 'response_schemas.yaml#/AccountBalanceResponseSchema' 7 | AccountUtxoResponse: 8 | description: Account utxos succcessful response 9 | content: 10 | application/json: 11 | schema: 12 | $ref: 'response_schemas.yaml#/AccountUtxoResponseSchema' 13 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/account/schemas.yaml: -------------------------------------------------------------------------------- 1 | AccountBalanceSchema: 2 | type: object 3 | properties: 4 | currency: 5 | type: string 6 | 7 | amount: 8 | type: integer 9 | format: int256 10 | 11 | AccountUtxoSchema: 12 | type: object 13 | properties: 14 | blknum: 15 | type: integer 16 | format: int64 17 | txindex: 18 | type: integer 19 | format: int16 20 | otype: 21 | type: integer 22 | format: int16 23 | oindex: 24 | type: integer 25 | format: int8 26 | utxo_pos: 27 | type: integer 28 | format: int256 29 | creating_txhash: 30 | type: string 31 | spending_txhash: 32 | type: string 33 | owner: 34 | type: string 35 | currency: 36 | type: string 37 | amount: 38 | type: integer 39 | format: int256 40 | inserted_at: 41 | type: string 42 | updated_at: 43 | type: string 44 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/alarm/paths.yaml: -------------------------------------------------------------------------------- 1 | alarm.get: 2 | get: 3 | tags: 4 | - Alarm 5 | summary: Provides alarms related to system memory, cpu and storage and application specific alarms. 6 | description: > 7 | **Note:** Service operator alarms. 8 | operationId: alarm_get 9 | responses: 10 | 200: 11 | $ref: 'responses.yaml#/AlarmResponse' 12 | 500: 13 | $ref: '../responses.yaml#/InternalServerError' 14 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/alarm/response_schemas.yaml: -------------------------------------------------------------------------------- 1 | AlarmResponseSchema: 2 | allOf: 3 | - $ref: '../response_schemas.yaml#/WatcherInfoBaseResponseSchema' 4 | - type: object 5 | properties: 6 | data: 7 | type: array 8 | items: 9 | $ref: 'schemas.yaml#/AlarmSchema' 10 | example: 11 | data: 12 | - 13 | disk_almost_full: "/dev/null" 14 | ethereum_connection_error: {} 15 | ethereum_stalled_sync: {} 16 | system_memory_high_watermark: [] 17 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/alarm/responses.yaml: -------------------------------------------------------------------------------- 1 | AlarmResponse: 2 | description: System alarms 3 | content: 4 | application/json: 5 | schema: 6 | $ref: 'response_schemas.yaml#/AlarmResponseSchema' -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/alarm/schemas.yaml: -------------------------------------------------------------------------------- 1 | AlarmSchema: 2 | type: array 3 | items: 4 | anyOf: 5 | - $ref: 'alarms_schema.yml#/components/schemas/ethereum_connection_error' 6 | - $ref: 'alarms_schema.yml#/components/schemas/ethereum_stalled_sync' 7 | - $ref: 'alarms_schema.yml#/components/schemas/invalid_fee_source' 8 | - $ref: 'alarms_schema.yml#/components/schemas/statsd_client_connection' 9 | - $ref: 'alarms_schema.yml#/components/schemas/system_memory_high_watermark' 10 | - $ref: 'alarms_schema.yml#/components/schemas/disk_almost_full' 11 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/batch_transaction/paths.yaml: -------------------------------------------------------------------------------- 1 | transaction.batch_submit: 2 | post: 3 | tags: 4 | - Transaction 5 | summary: This endpoint submits an array of signed transaction to the child chain. 6 | description: > 7 | Normally you should call the Watcher's Transaction - Submit instead of this. 8 | The Watcher's version performs various security and validation checks (TO DO) before submitting the transaction, 9 | so is much safer. However, if the Watcher is not available this version exists. 10 | operationId: batch_submit 11 | requestBody: 12 | $ref: 'request_bodies.yaml#/TransactionBatchSubmitBodySchema' 13 | responses: 14 | 200: 15 | $ref: 'responses.yaml#/TransactionBatchSubmitResponse' 16 | 500: 17 | $ref: '../responses.yaml#/InternalServerError' 18 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/batch_transaction/request_bodies.yaml: -------------------------------------------------------------------------------- 1 | TransactionBatchSubmitBodySchema: 2 | description: Array of signed transactions, RLP-encoded to bytes, and HEX-encoded to string 3 | required: true 4 | content: 5 | application/json: 6 | schema: 7 | title: 'TransactionBatchSubmitBodySchema' 8 | type: object 9 | properties: 10 | transactions: 11 | type: array 12 | items: 13 | type: string 14 | required: 15 | - transactions 16 | example: 17 | transactions: ['0xf8d083015ba98080808080940000...', '0xf8d083a15ba98080808080920000...'] 18 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/batch_transaction/response_schemas.yaml: -------------------------------------------------------------------------------- 1 | TransactionBatchSubmitResponseSchema: 2 | allOf: 3 | - $ref: '../response_schemas.yaml#/WatcherBaseResponseSchema' 4 | - type: object 5 | properties: 6 | data: 7 | type: array 8 | $ref: 'schemas.yaml#/TransactionBatchSubmitSchema ' 9 | example: 10 | data: 11 | - 12 | blknum: 123000 13 | txindex: 111 14 | txhash: '0xbdf562c24ace032176e27621073df58ce1c6f65de3b5932343b70ba03c72132d' 15 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/batch_transaction/responses.yaml: -------------------------------------------------------------------------------- 1 | TransactionBatchSubmitResponse: 2 | description: Transaction batch submission successful response 3 | content: 4 | application/json: 5 | schema: 6 | $ref: 'response_schemas.yaml#/TransactionBatchSubmitResponseSchema' 7 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/batch_transaction/schemas.yaml: -------------------------------------------------------------------------------- 1 | TransactionBatchSubmitSchema: 2 | type: array 3 | items: 4 | type: object 5 | properties: 6 | blknum: 7 | type: integer 8 | format: int64 9 | txindex: 10 | type: integer 11 | format: int16 12 | txhash: 13 | type: string 14 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/block/request_bodies.yaml: -------------------------------------------------------------------------------- 1 | AllBlocksBodySchema: 2 | description: The supported request parameters for /block.all 3 | content: 4 | application/json: 5 | schema: 6 | title: 'AllBlocksBodySchema' 7 | type: object 8 | properties: 9 | page: 10 | type: integer 11 | format: int32 12 | default: 1 13 | limit: 14 | type: integer 15 | format: int32 16 | default: 100 17 | example: 18 | page: 2 19 | limit: 100 20 | 21 | GetBlockBodySchema: 22 | description: Block number 23 | required: true 24 | content: 25 | application/json: 26 | schema: 27 | title: 'GetBlockBodySchema' 28 | type: object 29 | properties: 30 | blknum: 31 | type: integer 32 | format: int64 33 | example: 34 | blknum: 68290000 35 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/block/responses.yaml: -------------------------------------------------------------------------------- 1 | BlocksAllResponse: 2 | description: Blocks succcessful response 3 | content: 4 | application/json: 5 | schema: 6 | $ref: 'response_schemas.yaml#/BlocksAllResponseSchema' 7 | BlockResponse: 8 | description: Block succcessful response 9 | content: 10 | application/json: 11 | schema: 12 | $ref: 'response_schemas.yaml#/BlockResponseSchema' -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/block/schemas.yaml: -------------------------------------------------------------------------------- 1 | BlockSchema: 2 | type: object 3 | properties: 4 | blknum: 5 | type: integer 6 | format: int64 7 | hash: 8 | type: string 9 | 10 | eth_height: 11 | type: integer 12 | format: int64 13 | timestamp: 14 | type: integer 15 | format: int64 16 | tx_count: 17 | type: integer 18 | format: int64 19 | 20 | inserted_at: 21 | type: string 22 | updated_at: 23 | type: string 24 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/configuration/configuration_schema.yml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | deposit_finality_margin: 4 | type: integer 5 | format: int256 6 | contract_semver: 7 | type: string 8 | network: 9 | type: string 10 | exit_processor_sla_margin: 11 | type: integer 12 | format: int256 -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/configuration/paths.yaml: -------------------------------------------------------------------------------- 1 | configuration.get: 2 | get: 3 | tags: 4 | - Configuration 5 | summary: Provides configuration values 6 | description: > 7 | **Note:** Configuration values. 8 | operationId: configuration_get 9 | responses: 10 | 200: 11 | $ref: 'responses.yaml#/ConfigurationResponse' 12 | 500: 13 | $ref: '../responses.yaml#/InternalServerError' 14 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/configuration/response_schemas.yaml: -------------------------------------------------------------------------------- 1 | ConfigurationResponseSchema: 2 | allOf: 3 | - $ref: '../response_schemas.yaml#/WatcherInfoBaseResponseSchema' 4 | - type: object 5 | properties: 6 | data: 7 | type: array 8 | items: 9 | $ref: 'schemas.yaml#/ConfigurationSchema' 10 | example: 11 | data: 12 | - 13 | deposit_finality_margin: 10 14 | contract_semver: "1.0.0.1+a1s29s8" 15 | exit_processor_sla_margin: 5520 16 | network: "RINKEBY" 17 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/configuration/responses.yaml: -------------------------------------------------------------------------------- 1 | ConfigurationResponse: 2 | description: Configuration response 3 | content: 4 | application/json: 5 | schema: 6 | $ref: 'response_schemas.yaml#/ConfigurationResponseSchema' -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/configuration/schemas.yaml: -------------------------------------------------------------------------------- 1 | ConfigurationSchema: 2 | type: object 3 | properties: 4 | deposit_finality_margin: 5 | type: integer 6 | format: int256 7 | contract_semver: 8 | type: string 9 | 10 | exit_processor_sla_margin: 11 | type: integer 12 | format: int256 13 | network: 14 | type: string 15 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/deposit/paths.yaml: -------------------------------------------------------------------------------- 1 | deposit.all: 2 | post: 3 | tags: 4 | - Deposit 5 | summary: Gets a paginated list of deposit for the given address. 6 | description: > 7 | Returns a list of deposits ordered by Ethereum height in descending order for the given address. 8 | 9 | 10 | operationId: deposit_all 11 | requestBody: 12 | $ref: 'request_bodies.yaml#/AllDepositsBodySchema' 13 | responses: 14 | 200: 15 | $ref: 'responses.yaml#/DepositsAllResponse' 16 | 500: 17 | $ref: '../responses.yaml#/InternalServerError' 18 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/deposit/request_bodies.yaml: -------------------------------------------------------------------------------- 1 | AllDepositsBodySchema: 2 | description: The supported request parameters for /deposit.all. The "limit" and "page" parameters are optional. 3 | required: true 4 | content: 5 | application/json: 6 | schema: 7 | title: 'AllDepositsBodySchema' 8 | type: object 9 | properties: 10 | address: 11 | type: string 12 | page: 13 | type: integer 14 | format: int32 15 | default: 1 16 | limit: 17 | type: integer 18 | format: int32 19 | default: 100 20 | 21 | 22 | example: 23 | page: 2 24 | limit: 100 25 | address: "0xb01cb6f56d798a62d1e0bace406c73a122c39c9d" -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/deposit/responses.yaml: -------------------------------------------------------------------------------- 1 | DepositsAllResponse: 2 | description: /deposit.all succcessful response 3 | content: 4 | application/json: 5 | schema: 6 | $ref: 'response_schemas.yaml#/DepositsAllResponseSchema' 7 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/deposit/schemas.yaml: -------------------------------------------------------------------------------- 1 | DepositSchema: 2 | type: object 3 | properties: 4 | event_type: 5 | type: string 6 | root_chain_txhash: 7 | type: string 8 | log_index: 9 | type: integer 10 | eth_height: 11 | type: integer 12 | format: int64 13 | inserted_at: 14 | type: string 15 | updated_at: 16 | type: string 17 | txoutputs: 18 | type: array 19 | items: 20 | $ref: '#/TransactionOutputSchema' 21 | 22 | TransactionOutputSchema: 23 | type: object 24 | properties: 25 | blknum: 26 | type: integer 27 | format: int64 28 | txindex: 29 | type: integer 30 | format: int16 31 | oindex: 32 | type: integer 33 | format: int8 34 | otype: 35 | type: integer 36 | format: int8 37 | utxo_pos: 38 | type: integer 39 | format: int256 40 | owner: 41 | type: string 42 | currency: 43 | type: string 44 | amount: 45 | type: integer 46 | format: int256 47 | creating_txhash: 48 | type: string 49 | spending_txhash: 50 | type: string 51 | inserted_at: 52 | type: string 53 | updated_at: 54 | type: string -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/fees/paths.yaml: -------------------------------------------------------------------------------- 1 | fees.all: 2 | post: 3 | tags: 4 | - Fees 5 | summary: This endpoint retrieves the list of fee tokens currently supported by the childchain and the current amount needed to perform a transaction. 6 | operationId: fees_all 7 | requestBody: 8 | $ref: 'request_bodies.yaml#/FeesAllBodySchema' 9 | responses: 10 | 200: 11 | $ref: 'responses.yaml#/AllFeesResponse' 12 | 500: 13 | $ref: '../responses.yaml#/InternalServerError' 14 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/fees/request_bodies.yaml: -------------------------------------------------------------------------------- 1 | FeesAllBodySchema: 2 | description: An optional array of currencies to filter, raises an error if one of the currencies is not supported. 3 | required: false 4 | content: 5 | application/json: 6 | schema: 7 | title: 'FeesAllBodySchema' 8 | type: object 9 | properties: 10 | currencies: 11 | type: array 12 | items: 13 | type: string 14 | 15 | tx_types: 16 | type: array 17 | items: 18 | type: integer 19 | example: 20 | currencies: ['0x0000000000000000000000000000000000000000'] 21 | tx_types: [1] 22 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/fees/response_schemas.yaml: -------------------------------------------------------------------------------- 1 | AllFeesResponseSchema: 2 | allOf: 3 | - $ref: '../response_schemas.yaml#/WatcherInfoBaseResponseSchema' 4 | - type: object 5 | properties: 6 | data: 7 | type: object 8 | $ref: 'schemas.yaml#/FeeAllSchema' 9 | example: 10 | data: 11 | '1': 12 | - 13 | currency: '0x0000000000000000000000000000000000000000' 14 | amount: 220000000000000 15 | subunit_to_unit: 1000000000000000000 16 | pegged_currency: 'USD' 17 | pegged_amount: 4 18 | pegged_subunit_to_unit: 100 19 | updated_at: '2019-01-01T10:10:10+00:00' 20 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/fees/responses.yaml: -------------------------------------------------------------------------------- 1 | AllFeesResponse: 2 | description: List of all supported fees response 3 | content: 4 | application/json: 5 | schema: 6 | $ref: 'response_schemas.yaml#/AllFeesResponseSchema' 7 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/fees/schemas.yaml: -------------------------------------------------------------------------------- 1 | FeeAllSchema: 2 | type: object 3 | additionalProperties: 4 | type: array 5 | items: 6 | $ref: '#/FeeItemSchema' 7 | 8 | FeeItemSchema: 9 | type: object 10 | properties: 11 | currency: 12 | type: string 13 | 14 | amount: 15 | type: integer 16 | format: int256 17 | subunit_to_unit: 18 | type: integer 19 | format: int256 20 | pegged_currency: 21 | type: string 22 | 23 | pegged_amount: 24 | type: integer 25 | format: int256 26 | pegged_subunit_to_unit: 27 | type: integer 28 | format: int256 29 | updated_at: 30 | type: string 31 | format: date-time -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/responses.yaml: -------------------------------------------------------------------------------- 1 | InternalServerError: 2 | description: Returns an internal server error 3 | content: 4 | application/json: 5 | schema: 6 | $ref: 'response_schemas.yaml#/WatcherInfoErrorResponseSchema' 7 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/stats/paths.yaml: -------------------------------------------------------------------------------- 1 | stats.get: 2 | post: 3 | tags: 4 | - Stats 5 | summary: Retrieves network statistics 6 | description: > 7 | Retrieves transaction count, block count and average block interval, both for all time and the last 24 hours. 8 | 9 | operationId: stats_get 10 | responses: 11 | 200: 12 | $ref: 'responses.yaml#/StatsGetResponse' 13 | 500: 14 | $ref: '../responses.yaml#/InternalServerError' 15 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/stats/response_schemas.yaml: -------------------------------------------------------------------------------- 1 | StatsGetResponseSchema: 2 | allOf: 3 | - $ref: '../response_schemas.yaml#/WatcherInfoBaseListResponseSchema' 4 | - type: object 5 | properties: 6 | data: 7 | type: object 8 | items: 9 | $ref: 'schemas.yaml#/StatsSchema' 10 | example: 11 | data: 12 | transaction_count: 13 | all_time: 4 14 | last_24_hours: 2 15 | block_count: 16 | all_time: 2 17 | last_24_hours: 1 18 | average_block_interval: 19 | all_time: 100 20 | last_24_hours: null -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/stats/responses.yaml: -------------------------------------------------------------------------------- 1 | StatsGetResponse: 2 | description: Stats Successful Response 3 | content: 4 | application/json: 5 | schema: 6 | $ref: 'response_schemas.yaml#/StatsGetResponseSchema' 7 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/stats/schemas.yaml: -------------------------------------------------------------------------------- 1 | StatsSchema: 2 | type: object 3 | properties: 4 | transaction_count: 5 | type: object 6 | properties: 7 | all_time: 8 | type: integer 9 | format: int64 10 | last_24_hours: 11 | type: integer 12 | format: int64 13 | block_count: 14 | type: object 15 | properties: 16 | all_time: 17 | type: integer 18 | format: int64 19 | last_24_hours: 20 | type: integer 21 | format: int64 22 | average_block_interval: 23 | type: object 24 | properties: 25 | all_time: 26 | type: number 27 | format: int64 28 | last_24_hours: 29 | type: number 30 | format: int64 31 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/info_api_specs/transaction/responses.yaml: -------------------------------------------------------------------------------- 1 | GetAllTransactionsResponse: 2 | description: Transactions succcessful response 3 | content: 4 | application/json: 5 | schema: 6 | $ref: 'response_schemas.yaml#/GetAllTransactionsResponseSchema' 7 | 8 | CreateTransactionResponse: 9 | description: Transaction create successful response 10 | content: 11 | application/json: 12 | schema: 13 | $ref: 'response_schemas.yaml#/CreateTransactionResponseSchema' 14 | 15 | MergeTransactionResponse: 16 | description: Transaction merge successful response 17 | content: 18 | application/json: 19 | schema: 20 | $ref: 'response_schemas.yaml#/MergeTransactionResponseSchema' 21 | 22 | GetTransactionResponse: 23 | description: Transaction details succcessful response 24 | content: 25 | application/json: 26 | schema: 27 | $ref: 'response_schemas.yaml#/GetTransactionResponseSchema' 28 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/account/paths.yaml: -------------------------------------------------------------------------------- 1 | account.get_exitable_utxos: 2 | post: 3 | tags: 4 | - Account 5 | summary: Gets all utxos belonging to the given address. 6 | description: > 7 | **Note:** this is a performance intensive call and should only be used if the chain is byzantine and the user needs to retrieve utxo information to be able to exit. 8 | Normally an application should use the Informational API's [Account - Get Utxos](http://TODO) instead. 9 | This version is provided in case the Informational API is not available. 10 | operationId: account_get_exitable_utxos 11 | requestBody: 12 | $ref: 'request_bodies.yaml#/AddressBodySchema' 13 | responses: 14 | 200: 15 | $ref: 'responses.yaml#/AccountUtxoResponse' 16 | 500: 17 | $ref: '../responses.yaml#/InternalServerError' 18 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/account/request_bodies.yaml: -------------------------------------------------------------------------------- 1 | AddressBodySchema: 2 | description: HEX-encoded address of the account 3 | required: true 4 | content: 5 | application/json: 6 | schema: 7 | title: 'AddressBodySchema' 8 | type: object 9 | properties: 10 | address: 11 | type: string 12 | 13 | required: 14 | - address 15 | example: 16 | address: '0xb3256026863eb6ae5b06fa396ab09069784ea8ea' 17 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/account/response_schemas.yaml: -------------------------------------------------------------------------------- 1 | AccountUtxoResponseSchema: 2 | allOf: 3 | - $ref: '../response_schemas.yaml#/WatcherBaseResponseSchema' 4 | - type: object 5 | properties: 6 | data: 7 | type: array 8 | items: 9 | $ref: 'schemas.yaml#/AccountUtxoSchema' 10 | example: 11 | data: 12 | - 13 | blknum: 123000 14 | txindex: 111 15 | oindex: 0 16 | otype: 1 17 | utxo_pos: 123000001110000 18 | owner: '0xb3256026863eb6ae5b06fa396ab09069784ea8ea' 19 | currency: '0x0000000000000000000000000000000000000000' 20 | amount: 10 21 | 22 | 23 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/account/responses.yaml: -------------------------------------------------------------------------------- 1 | AccountUtxoResponse: 2 | description: Account utxos succcessful response 3 | content: 4 | application/json: 5 | schema: 6 | $ref: 'response_schemas.yaml#/AccountUtxoResponseSchema' -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/account/schemas.yaml: -------------------------------------------------------------------------------- 1 | AccountUtxoSchema: 2 | type: object 3 | properties: 4 | blknum: 5 | type: integer 6 | format: int64 7 | txindex: 8 | type: integer 9 | format: int16 10 | otype: 11 | type: integer 12 | format: int16 13 | oindex: 14 | type: integer 15 | format: int8 16 | utxo_pos: 17 | type: integer 18 | format: int256 19 | owner: 20 | type: string 21 | currency: 22 | type: string 23 | amount: 24 | type: integer 25 | format: int256 26 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/alarm/paths.yaml: -------------------------------------------------------------------------------- 1 | alarm.get: 2 | get: 3 | tags: 4 | - Alarm 5 | summary: Provides alarms related to system memory, cpu and storage and application specific alarms. 6 | description: > 7 | **Note:** Service operator alarms. 8 | operationId: alarm_get 9 | responses: 10 | 200: 11 | $ref: 'responses.yaml#/AlarmResponse' 12 | 500: 13 | $ref: '../responses.yaml#/InternalServerError' 14 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/alarm/response_schemas.yaml: -------------------------------------------------------------------------------- 1 | AlarmResponseSchema: 2 | allOf: 3 | - $ref: '../response_schemas.yaml#/WatcherBaseResponseSchema' 4 | - type: object 5 | properties: 6 | data: 7 | type: array 8 | items: 9 | $ref: 'schemas.yaml#/AlarmSchema' 10 | example: 11 | data: 12 | - 13 | disk_almost_full: "/dev/null" 14 | ethereum_connection_error: {} 15 | ethereum_stalled_sync: {} 16 | system_memory_high_watermark: [] 17 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/alarm/responses.yaml: -------------------------------------------------------------------------------- 1 | AlarmResponse: 2 | description: System alarms 3 | content: 4 | application/json: 5 | schema: 6 | $ref: 'response_schemas.yaml#/AlarmResponseSchema' -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/alarm/schemas.yaml: -------------------------------------------------------------------------------- 1 | AlarmSchema: 2 | type: array 3 | items: 4 | anyOf: 5 | - $ref: 'alarms_schema.yml#/components/schemas/ethereum_connection_error' 6 | - $ref: 'alarms_schema.yml#/components/schemas/ethereum_stalled_sync' 7 | - $ref: 'alarms_schema.yml#/components/schemas/invalid_fee_source' 8 | - $ref: 'alarms_schema.yml#/components/schemas/statsd_client_connection' 9 | - $ref: 'alarms_schema.yml#/components/schemas/system_memory_high_watermark' 10 | - $ref: 'alarms_schema.yml#/components/schemas/disk_almost_full' 11 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/batch_transaction/paths.yaml: -------------------------------------------------------------------------------- 1 | transaction.batch_submit: 2 | post: 3 | tags: 4 | - Transaction 5 | summary: This endpoint submits an array of signed transaction to the child chain. 6 | description: > 7 | Normally you should call the Watcher's Transaction - Submit instead of this. 8 | The Watcher's version performs various security and validation checks (TO DO) before submitting the transaction, 9 | so is much safer. However, if the Watcher is not available this version exists. 10 | operationId: batch_submit 11 | requestBody: 12 | $ref: 'request_bodies.yaml#/TransactionBatchSubmitBodySchema' 13 | responses: 14 | 200: 15 | $ref: 'responses.yaml#/TransactionBatchSubmitResponse' 16 | 500: 17 | $ref: '../responses.yaml#/InternalServerError' 18 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/batch_transaction/request_bodies.yaml: -------------------------------------------------------------------------------- 1 | TransactionBatchSubmitBodySchema: 2 | description: Array of signed transactions, RLP-encoded to bytes, and HEX-encoded to string 3 | required: true 4 | content: 5 | application/json: 6 | schema: 7 | title: 'TransactionBatchSubmitBodySchema' 8 | type: object 9 | properties: 10 | transactions: 11 | type: array 12 | items: 13 | type: string 14 | required: 15 | - transactions 16 | example: 17 | transactions: ['0xf8d083015ba98080808080940000...', '0xf8d083a15ba98080808080920000...'] 18 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/batch_transaction/response_schemas.yaml: -------------------------------------------------------------------------------- 1 | TransactionBatchSubmitResponseSchema: 2 | allOf: 3 | - $ref: '../response_schemas.yaml#/WatcherBaseResponseSchema' 4 | - type: object 5 | properties: 6 | data: 7 | type: array 8 | $ref: 'schemas.yaml#/TransactionBatchSubmitSchema ' 9 | example: 10 | data: 11 | - 12 | blknum: 123000 13 | txindex: 111 14 | txhash: '0xbdf562c24ace032176e27621073df58ce1c6f65de3b5932343b70ba03c72132d' 15 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/batch_transaction/responses.yaml: -------------------------------------------------------------------------------- 1 | TransactionBatchSubmitResponse: 2 | description: Transaction batch submission successful response 3 | content: 4 | application/json: 5 | schema: 6 | $ref: 'response_schemas.yaml#/TransactionBatchSubmitResponseSchema' 7 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/batch_transaction/schemas.yaml: -------------------------------------------------------------------------------- 1 | TransactionBatchSubmitSchema: 2 | type: array 3 | items: 4 | type: object 5 | properties: 6 | blknum: 7 | type: integer 8 | format: int64 9 | txindex: 10 | type: integer 11 | format: int16 12 | txhash: 13 | type: string 14 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/block/paths.yaml: -------------------------------------------------------------------------------- 1 | block.validate: 2 | post: 3 | tags: 4 | - Block 5 | summary: Verifies the stateless validity of a block. 6 | description: | 7 | - Verifies that given Merkle root matches reconstructed Merkle root. 8 | - Verifies that (payment and fee) transactions are correctly formed. 9 | - Verifies that there are no duplicate inputs at the block level. 10 | - Verifies that the number of transactions falls within the accepted range. 11 | - Verifies that fee transactions are correctly placed and unique per currency. 12 | operationId: validate 13 | requestBody: 14 | $ref: 'request_bodies.yaml#/BlockValidateBodySchema' 15 | responses: 16 | 200: 17 | $ref: 'responses.yaml#/BlockValidateResponse' 18 | 500: 19 | $ref: '../responses.yaml#/InternalServerError' 20 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/block/request_bodies.yaml: -------------------------------------------------------------------------------- 1 | BlockValidateBodySchema: 2 | description: Block object with a hash, number and array of hexadecimal transaction bytes. 3 | required: true 4 | content: 5 | application/json: 6 | schema: 7 | title: 'BlockValidateBodySchema' 8 | type: object 9 | properties: 10 | hash: 11 | type: string 12 | transactions: 13 | type: array 14 | items: 15 | type: string 16 | number: 17 | type: integer 18 | required: 19 | - hash 20 | - transactions 21 | - number 22 | example: 23 | number: 1000 24 | hash: '0xf8d083015ba98080808080940000...' 25 | transactions: ["0xf8c0f843b841fc6dbf49a4baa783ec576291f6083be5ea...", "0xf852c003eeed02eb94916f3753bd53e124d6d565ef1701..." ] 26 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/block/response_schemas.yaml: -------------------------------------------------------------------------------- 1 | BlockValidateResponseSchema: 2 | allOf: 3 | - $ref: '../response_schemas.yaml#/WatcherBaseResponseSchema' 4 | - type: object 5 | properties: 6 | data: 7 | type: object 8 | $ref: 'schemas.yaml#/BlockValidateSchema' 9 | example: 10 | data: 11 | valid: false 12 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/block/responses.yaml: -------------------------------------------------------------------------------- 1 | BlockValidateResponse: 2 | description: Successful response to calling /block.validate 3 | content: 4 | application/json: 5 | schema: 6 | $ref: 'response_schemas.yaml#/BlockValidateResponseSchema' 7 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/block/schemas.yaml: -------------------------------------------------------------------------------- 1 | BlockValidateSchema: 2 | type: object 3 | properties: 4 | valid: 5 | type: boolean 6 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/configuration/configuration_schema.yml: -------------------------------------------------------------------------------- 1 | components: 2 | schemas: 3 | deposit_finality_margin: 4 | type: integer 5 | contract_semver: 6 | type: string 7 | exit_processor_sla_margin: 8 | type: integer 9 | network: 10 | type: string 11 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/configuration/paths.yaml: -------------------------------------------------------------------------------- 1 | configuration.get: 2 | get: 3 | tags: 4 | - Configuration 5 | summary: Provides configuration values 6 | description: > 7 | **Note:** Configuration values. 8 | operationId: configuration_get 9 | responses: 10 | 200: 11 | $ref: 'responses.yaml#/ConfigurationResponse' 12 | 500: 13 | $ref: '../responses.yaml#/InternalServerError' 14 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/configuration/response_schemas.yaml: -------------------------------------------------------------------------------- 1 | ConfigurationResponseSchema: 2 | allOf: 3 | - $ref: '../response_schemas.yaml#/WatcherBaseResponseSchema' 4 | - type: object 5 | properties: 6 | data: 7 | type: array 8 | items: 9 | $ref: 'schemas.yaml#/ConfigurationSchema' 10 | example: 11 | data: 12 | - 13 | deposit_finality_margin: 10 14 | contract_semver: "1.0.0.1+a1s29s8" 15 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/configuration/responses.yaml: -------------------------------------------------------------------------------- 1 | ConfigurationResponse: 2 | description: Configuration response 3 | content: 4 | application/json: 5 | schema: 6 | $ref: 'response_schemas.yaml#/ConfigurationResponseSchema' -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/configuration/schemas.yaml: -------------------------------------------------------------------------------- 1 | ConfigurationSchema: 2 | type: object 3 | properties: 4 | deposit_finality_margin: 5 | type: integer 6 | format: int256 7 | contract_semver: 8 | type: string 9 | 10 | exit_processor_sla_margin: 11 | type: integer 12 | format: int256 13 | network: 14 | type: string 15 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/in_flight_exit/responses.yaml: -------------------------------------------------------------------------------- 1 | GetInFlightExitDataResponse: 2 | description: Get in-flight exit successful response 3 | content: 4 | application/json: 5 | schema: 6 | $ref: 'response_schemas.yaml#/GetInFlightExitDataResponseSchema' 7 | 8 | GetCompetitorResponse: 9 | description: Get competitor successful response 10 | content: 11 | application/json: 12 | schema: 13 | $ref: 'response_schemas.yaml#/GetCompetitorResponseSchema' 14 | 15 | ProveCanonicalResponse: 16 | description: Prove canonical successful response 17 | content: 18 | application/json: 19 | schema: 20 | $ref: 'response_schemas.yaml#/ProveCanonicalResponseSchema' 21 | 22 | InputChallengeDataResponse: 23 | description: Get input challenge successful response 24 | content: 25 | application/json: 26 | schema: 27 | $ref: 'response_schemas.yaml#/InputChallengeDataResponseSchema' 28 | 29 | OutputChallengeDataResponse: 30 | description: Get output challenge successful response 31 | content: 32 | application/json: 33 | schema: 34 | $ref: 'response_schemas.yaml#/OutputChallengeDataResponseSchema' 35 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/responses.yaml: -------------------------------------------------------------------------------- 1 | InternalServerError: 2 | description: Returns an internal server error 3 | content: 4 | application/json: 5 | schema: 6 | $ref: 'response_schemas.yaml#/WatcherErrorResponseSchema' 7 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/status/paths.yaml: -------------------------------------------------------------------------------- 1 | status.get: 2 | post: 3 | tags: 4 | - Status 5 | summary: Returns information about the current state of the child chain and the watcher. 6 | description: > 7 | The most critical function of the Watcher is to monitor the ChildChain and report dishonest activity. 8 | The user must call the `/status.get` endpoint periodically to check. Any situation that requires the user 9 | to either exit or challenge an invalid exit will be included in the `byzantine_events` field. 10 | operationId: status_get 11 | responses: 12 | 200: 13 | $ref: 'responses.yaml#/StatusResponse' 14 | 500: 15 | $ref: '../responses.yaml#/InternalServerError' 16 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/status/request_bodies.yaml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/status/responses.yaml: -------------------------------------------------------------------------------- 1 | StatusResponse: 2 | description: Returns the status of the watcher 3 | content: 4 | application/json: 5 | schema: 6 | $ref: 'response_schemas.yaml#/StatusResponseSchema' 7 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/transaction/paths.yaml: -------------------------------------------------------------------------------- 1 | transaction.submit: 2 | post: 3 | tags: 4 | - Transaction 5 | summary: Sends transaction to Child chain. 6 | description: Watcher passes signed transaction to the child chain only if it's secure, e.g. Watcher is fully synced, all operator blocks have been verified, transaction doesn't spend funds not yet mined... 7 | operationId: submit 8 | requestBody: 9 | $ref: 'request_bodies.yaml#/TransactionSubmitBodySchema' 10 | responses: 11 | 200: 12 | $ref: 'responses.yaml#/TransactionSubmitResponse' 13 | 500: 14 | $ref: '../responses.yaml#/InternalServerError' 15 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/transaction/request_bodies.yaml: -------------------------------------------------------------------------------- 1 | TransactionSubmitBodySchema: 2 | description: Signed transaction RLP-encoded to bytes and HEX-encoded to string 3 | required: true 4 | content: 5 | application/json: 6 | schema: 7 | title: 'TransactionSubmitBodySchema' 8 | type: object 9 | properties: 10 | transaction: 11 | type: string 12 | 13 | required: 14 | - transaction 15 | example: 16 | transaction: '0xf8d083015ba98080808080940000...' 17 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/transaction/response_schemas.yaml: -------------------------------------------------------------------------------- 1 | TransactionSubmitResponseSchema: 2 | allOf: 3 | - $ref: '../response_schemas.yaml#/WatcherBaseResponseSchema' 4 | - type: object 5 | properties: 6 | data: 7 | type: object 8 | $ref: 'schemas.yaml#/TransactionSubmitSchema' 9 | example: 10 | data: 11 | blknum: 123000 12 | txindex: 111 13 | txhash: '0xbdf562c24ace032176e27621073df58ce1c6f65de3b5932343b70ba03c72132d' 14 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/transaction/responses.yaml: -------------------------------------------------------------------------------- 1 | TransactionSubmitResponse: 2 | description: Transaction submission successful response 3 | content: 4 | application/json: 5 | schema: 6 | $ref: 'response_schemas.yaml#/TransactionSubmitResponseSchema' 7 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/transaction/schemas.yaml: -------------------------------------------------------------------------------- 1 | TransactionSubmitSchema: 2 | type: object 3 | properties: 4 | blknum: 5 | type: integer 6 | format: int64 7 | txindex: 8 | type: integer 9 | format: int16 10 | txhash: 11 | type: string 12 | 13 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/utxo/paths.yaml: -------------------------------------------------------------------------------- 1 | utxo.get_challenge_data: 2 | post: 3 | tags: 4 | - UTXO 5 | summary: Gets challenge data for a given utxo exit. 6 | description: Gets challenge data for a given utxo exit. 7 | operationId: utxo_get_challenge_data 8 | requestBody: 9 | $ref: 'request_bodies.yaml#/UtxoPositionBodySchema' 10 | responses: 11 | 200: 12 | $ref: 'responses.yaml#/GetUtxoChallengeResponse' 13 | 500: 14 | $ref: '../responses.yaml#/InternalServerError' 15 | 16 | utxo.get_exit_data: 17 | post: 18 | tags: 19 | - UTXO 20 | summary: Gets exit data for a given utxo. 21 | description: Gets exit data for a given utxo. 22 | operationId: utxo_get_exit_data 23 | requestBody: 24 | $ref: 'request_bodies.yaml#/UtxoPositionBodySchema' 25 | responses: 26 | 200: 27 | $ref: 'responses.yaml#/GetUtxoExitResponse' 28 | 500: 29 | $ref: '../responses.yaml#/InternalServerError' 30 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/utxo/request_bodies.yaml: -------------------------------------------------------------------------------- 1 | UtxoPositionBodySchema: 2 | description: Utxo position (encoded as single integer, the way contract represents them) 3 | required: true 4 | content: 5 | application/json: 6 | schema: 7 | title: 'UtxoPositionBodySchema' 8 | type: object 9 | properties: 10 | utxo_pos: 11 | type: integer 12 | format: int256 13 | required: 14 | - utxo_pos 15 | example: 16 | utxo_pos: 10000000010000000 17 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/utxo/response_schemas.yaml: -------------------------------------------------------------------------------- 1 | GetUtxoChallengeResponseSchema: 2 | description: The response schema for utxo challenge data 3 | allOf: 4 | - $ref: '../response_schemas.yaml#/WatcherBaseResponseSchema' 5 | - type: object 6 | properties: 7 | data: 8 | type: object 9 | $ref: 'schemas.yaml#/GetUtxoChallengeSchema' 10 | example: 11 | data: 12 | exit_id: 1717611893014159315373779059565546411346446754 13 | input_index: 0 14 | sig: '0x6bfb9b2dbe32...' 15 | txbytes: '0x3eb6ae5b06f3...' 16 | exiting_tx: '0x6d6bda6bd6d6...' 17 | 18 | GetUtxoExitResponseSchema: 19 | description: The response schema for utxo exit data 20 | allOf: 21 | - $ref: '../response_schemas.yaml#/WatcherBaseResponseSchema' 22 | - type: object 23 | properties: 24 | data: 25 | type: object 26 | $ref: 'schemas.yaml#/GetUtxoExitSchema' 27 | example: 28 | data: 29 | proof: '0xcedb8b31d1e4...' 30 | txbytes: '0x3eb6ae5b06f3...' 31 | utxo_pos: 10000000010000000 32 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/utxo/responses.yaml: -------------------------------------------------------------------------------- 1 | GetUtxoChallengeResponse: 2 | description: Utxo challenge successful response 3 | content: 4 | application/json: 5 | schema: 6 | $ref: 'response_schemas.yaml#/GetUtxoChallengeResponseSchema' 7 | 8 | GetUtxoExitResponse: 9 | description: Utxo exit successful response 10 | content: 11 | application/json: 12 | schema: 13 | $ref: 'response_schemas.yaml#/GetUtxoExitResponseSchema' 14 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/security_critical_api_specs/utxo/schemas.yaml: -------------------------------------------------------------------------------- 1 | GetUtxoChallengeSchema: 2 | type: object 3 | properties: 4 | exit_id: 5 | type: integer 6 | format: int192 7 | input_index: 8 | type: integer 9 | format: int8 10 | sig: 11 | type: string 12 | 13 | txbytes: 14 | type: string 15 | 16 | exiting_tx: 17 | type: string 18 | 19 | 20 | GetUtxoExitSchema: 21 | type: object 22 | properties: 23 | utxo_pos: 24 | type: integer 25 | format: int256 26 | txbytes: 27 | type: string 28 | 29 | proof: 30 | type: string 31 | 32 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/shared/paths.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omgnetwork/elixir-omg/2c68973d8f29033d137f63a6e060f12e2a7dcd59/apps/omg_watcher_rpc/priv/swagger/shared/paths.yaml -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/shared/request_bodies.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omgnetwork/elixir-omg/2c68973d8f29033d137f63a6e060f12e2a7dcd59/apps/omg_watcher_rpc/priv/swagger/shared/request_bodies.yaml -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/priv/swagger/shared/schemas.yaml: -------------------------------------------------------------------------------- 1 | ErrorSchema: 2 | description: The object schema for an error 3 | type: object 4 | properties: 5 | object: 6 | type: string 7 | code: 8 | type: string 9 | description: 10 | type: string 11 | messages: 12 | type: object 13 | required: 14 | - object 15 | - code 16 | - description 17 | - messages 18 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/test/omg_watcher_rpc/web/controllers/fallback_test.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.WatcherRPC.Web.Controller.FallbackTest do 16 | use ExUnitFixtures 17 | use ExUnit.Case, async: false 18 | use OMG.WatcherInfo.Fixtures 19 | 20 | alias Support.WatcherHelper 21 | 22 | @tag fixtures: [:phoenix_ecto_sandbox] 23 | test "returns error for non existing method" do 24 | assert %{ 25 | "object" => "error", 26 | "code" => "operation:not_found", 27 | "description" => "Operation cannot be found. Check request URL." 28 | } == WatcherHelper.no_success?("no_such.endpoint", %{}) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/test/omg_watcher_rpc/web/controllers/status_test.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.WatcherRPC.Web.Controller.StatusTest do 16 | use ExUnitFixtures 17 | use ExUnit.Case, async: false 18 | 19 | @moduletag :integration 20 | @moduletag :watcher 21 | # a test in OMG.WatcherInfo.Integration.StatusTest fully tests the controller, 22 | # but it needs whole system setup so it's declared as integration test 23 | end 24 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/test/omg_watcher_rpc/web/view_case.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule OMG.WatcherRPC.ViewCase do 16 | @moduledoc """ 17 | This module defines common behaviors shared between view tests. 18 | """ 19 | use ExUnit.CaseTemplate 20 | 21 | using do 22 | quote do 23 | use ExUnit.Case 24 | import Phoenix.View 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /apps/omg_watcher_rpc/test/test_helper.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | ExUnit.configure(exclude: [mix_based_child_chain: true, integration: true, property: true, wrappers: true]) 16 | ExUnitFixtures.start() 17 | ExUnit.start() 18 | 19 | {:ok, _} = Application.ensure_all_started(:httpoison) 20 | {:ok, _} = Application.ensure_all_started(:fake_server) 21 | {:ok, _} = Application.ensure_all_started(:ex_machina) 22 | 23 | Mix.Task.run("ecto.create", ~w(--quiet)) 24 | Mix.Task.run("ecto.migrate", ~w(--quiet)) 25 | -------------------------------------------------------------------------------- /apps/xomg_tasks/lib/mix/tasks/watcher.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule Mix.Tasks.Xomg.Watcher.Start do 16 | @moduledoc """ 17 | Contains mix.task to run the watcher in security-critical only modes. 18 | 19 | See the README.md file. 20 | """ 21 | use Mix.Task 22 | 23 | import XomgTasks.Utils 24 | 25 | @shortdoc "Starts the security-critical watcher. See Mix.Tasks.Watcher." 26 | 27 | def run(args) do 28 | args 29 | |> config_db("--db") 30 | |> generic_prepare_args() 31 | |> generic_run([:omg_watcher, :omg_watcher_rpc]) 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /apps/xomg_tasks/lib/mix/tasks/watcher_info.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule Mix.Tasks.Xomg.WatcherInfo.Start do 16 | @moduledoc """ 17 | Contains mix.task to run the watcher in security-critical + informational mode. 18 | 19 | See the README.md file. 20 | """ 21 | use Mix.Task 22 | 23 | import XomgTasks.Utils 24 | 25 | @shortdoc "Starts the security-critical + informational watcher. See Mix.Tasks.Xomg.WatcherInfo.Start." 26 | 27 | def run(args) do 28 | args 29 | |> generic_prepare_args() 30 | |> generic_run([:omg_watcher_info, :omg_watcher_rpc]) 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /apps/xomg_tasks/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule OMG.XomgTasks.MixProject do 2 | @moduledoc """ 3 | This is just a proxy app to hold and use all the code related to running `xomg` Mix.Tasks. 4 | 5 | NOTE: this is not a proper mix app, just some Mix.Tasks which call into other mix apps 6 | """ 7 | use Mix.Project 8 | 9 | def project() do 10 | [ 11 | app: :xomg_tasks, 12 | version: version(), 13 | build_path: "../../_build", 14 | deps_path: "../../deps", 15 | lockfile: "../../mix.lock", 16 | elixir: "~> 1.8", 17 | elixirc_paths: ["lib"], 18 | start_permanent: false, 19 | deps: [] 20 | ] 21 | end 22 | 23 | def application() do 24 | [extra_applications: [:iex, :logger]] 25 | end 26 | 27 | defp version() do 28 | "git" 29 | |> System.cmd(["describe", "--tags", "--abbrev=0"]) 30 | |> elem(0) 31 | |> String.replace("v", "") 32 | |> String.replace("\n", "") 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /apps/xomg_tasks/test/test_helper.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /bin/revert: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This is for geth 4 | # https://gist.github.com/gluk64/fdea559472d957f1138ed93bcbc6f78a 5 | # Fetching revert reason -- https://ethereum.stackexchange.com/questions/48383/how-to-receive-revert-reason-for-past-transactions 6 | 7 | if [ -z "$1" ] 8 | then 9 | echo "Usage: revert-reason " 10 | exit 11 | fi 12 | 13 | TX=$1 14 | SCRIPT=" tx = eth.getTransaction( \"$TX\" ); tx.data = tx.input; eth.call(tx, tx.blockNumber)" 15 | 16 | geth --exec "$SCRIPT" attach http://localhost:8545 | cut -d '"' -f 2 | cut -c139- | xxd -r -p 17 | echo -------------------------------------------------------------------------------- /bin/variables: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | export APP_ENV=local-development 3 | export HOSTNAME=http://localhost/ 4 | export DB_PATH=~/plasma-data/ 5 | export ETHEREUM_RPC_URL=http://127.0.0.1:8545 6 | export ETH_NODE=geth 7 | export ETHEREUM_NETWORK=LOCALCHAIN 8 | export DATABASE_URL=postgresql://omisego_dev:omisego_dev@127.0.0.1:5432/omisego_dev 9 | export CHILD_CHAIN_URL=http://127.0.0.1:9656 10 | export ETHEREUM_HEIGHT_CHECK_INTERVAL_MS=800 11 | export ETHEREUM_EVENTS_CHECK_INTERVAL_MS=800 12 | export ETHEREUM_STALLED_SYNC_THRESHOLD_MS=20000 13 | export EXIT_PROCESSOR_SLA_MARGIN=5520 14 | export FEE_CLAIMER_ADDRESS=0x3b9f4c1dd26e0be593373b1d36cee2008cbeb837 15 | export FEE_ADAPTER=feed 16 | export FEE_FEED_URL=http://127.0.0.1:4000/api/v1 17 | export STORED_FEE_UPDATE_INTERVAL_MINUTES=1 18 | export FEE_CHANGE_TOLERANCE_PERCENT=1 19 | export FEE_SPECS_FILE_PATH=./priv/dev-artifacts/fee_specs.dev.json 20 | export DD_HOSTNAME=localhost 21 | export DD_DISABLED=true 22 | export LOGGER_BACKEND=console 23 | export RELEASE_COOKIE=development 24 | export NODE_HOST=127.0.0.1 25 | # expects it's executed from the root of the project 26 | FILE='./localchain_contract_addresses.env' 27 | while IFS= read -r line; do 28 | DATA_TO_EXPORT='export '$line 29 | eval $DATA_TO_EXPORT 30 | done < ${FILE} 31 | -------------------------------------------------------------------------------- /config/dev.exs: -------------------------------------------------------------------------------- 1 | import Config 2 | 3 | config :logger, 4 | backends: [:console, Sentry.LoggerBackend] 5 | 6 | config :omg_watcher, 7 | ethereum_events_check_interval_ms: 500, 8 | coordinator_eth_height_check_interval_ms: 1_000 9 | 10 | config :omg_db, 11 | path: Path.join([System.get_env("HOME"), ".omg/data"]) 12 | 13 | config :ethereumex, 14 | http_options: [recv_timeout: 60_000] 15 | 16 | config :omg_eth, 17 | min_exit_period_seconds: 10 * 60, 18 | ethereum_block_time_seconds: 1, 19 | node_logging_in_debug: true 20 | 21 | config :omg_watcher_rpc, environment: :dev 22 | config :phoenix, :stacktrace_depth, 20 23 | 24 | config :omg_watcher_rpc, OMG.WatcherRPC.Tracer, 25 | disabled?: true, 26 | env: "development" 27 | 28 | config :omg_watcher_info, environment: :dev 29 | 30 | config :omg_watcher_info, OMG.WatcherInfo.Tracer, 31 | disabled?: true, 32 | env: "development" 33 | 34 | config :omg_watcher, environment: :dev 35 | 36 | config :omg_watcher, 37 | # 1 hour of Ethereum blocks 38 | exit_processor_sla_margin: 60 * 4, 39 | # this means we allow the `sla_margin` above be larger than the `min_exit_period` 40 | exit_processor_sla_margin_forced: true 41 | 42 | config :omg_watcher, OMG.Watcher.Tracer, 43 | disabled?: true, 44 | env: "development" 45 | 46 | config :omg_status, OMG.Status.Metric.Tracer, 47 | env: "development", 48 | disabled?: true 49 | -------------------------------------------------------------------------------- /config/prod.exs: -------------------------------------------------------------------------------- 1 | use Mix.Config 2 | -------------------------------------------------------------------------------- /contract_addresses_template.env: -------------------------------------------------------------------------------- 1 | AUTHORITY_ADDRESS={AUTHORITY_ADDRESS} 2 | CONTRACT_ADDRESS_ETH_VAULT={CONTRACT_ADDRESS_ETH_VAULT} 3 | CONTRACT_ADDRESS_ERC20_VAULT={CONTRACT_ADDRESS_ERC20_VAULT} 4 | CONTRACT_ADDRESS_PAYMENT_EXIT_GAME={CONTRACT_ADDRESS_PAYMENT_EXIT_GAME} 5 | CONTRACT_ADDRESS_PLASMA_FRAMEWORK={CONTRACT_ADDRESS_PLASMA_FRAMEWORK} 6 | TXHASH_CONTRACT={TXHASH_CONTRACT} 7 | CONTRACT_ADDRESS_PAYMENT_EIP_712_LIB_MOCK={CONTRACT_ADDRESS_PAYMENT_EIP_712_LIB_MOCK} 8 | CONTRACT_ADDRESS_MERKLE_WRAPPER={CONTRACT_ADDRESS_MERKLE_WRAPPER} 9 | CONTRACT_ERC20_MINTABLE={CONTRACT_ERC20_MINTABLE} 10 | -------------------------------------------------------------------------------- /coveralls.json: -------------------------------------------------------------------------------- 1 | { 2 | "skip_files": [ 3 | "apps/omg/test/support", 4 | "apps/omg_bus/test/support", 5 | "apps/omg_db/test/support", 6 | "apps/omg_eth/test/support", 7 | "apps/omg_status/test/support", 8 | "apps/omg_utils/test/support", 9 | "apps/omg_watcher/test/support", 10 | "apps/omg_watcher_info/test/support", 11 | "apps/omg_watcher_info/lib/omg_watcher_info/release_tasks/init_postgresql_db.ex", 12 | "apps/omg_watcher_rpc/test/support", 13 | "apps/xomg_tasks" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /docker-compose-infura.yml: -------------------------------------------------------------------------------- 1 | version: "2.3" 2 | services: 3 | plasma-contracts: 4 | environment: 5 | # The private keys are likely different from the main docker-compose.yml: 6 | # 1. DEPLOYER_PRIVATEKEY needs to have enough ETH on the REMOTE_URL network 7 | # 2. AUTHORITY_PRIVATEKEY needs to have nonce=0 on the REMOTE_URL network 8 | - REMOTE_URL=https://rinkeby.infura.io/v3/${INFURA_API_KEY} 9 | - DEPLOYER_PRIVATEKEY=${DEPLOYER_PRIVATEKEY} 10 | - MAINTAINER_PRIVATEKEY=${MAINTAINER_PRIVATEKEY} 11 | - AUTHORITY_PRIVATEKEY=${AUTHORITY_PRIVATEKEY} 12 | 13 | childchain: 14 | environment: 15 | - ETHEREUM_RPC_URL=https://rinkeby.infura.io/v3/${INFURA_API_KEY} 16 | - PRIVATE_KEY=${AUTHORITY_PRIVATEKEY} 17 | 18 | watcher: 19 | environment: 20 | - ETHEREUM_RPC_URL=https://rinkeby.infura.io/v3/${INFURA_API_KEY} 21 | 22 | geth: 23 | # We don't need geth but docker-compose doesn't support overrides to remove or disable a service 24 | # So here we set `--dev.period 0` to minimize resource utilization. 25 | entrypoint: /bin/sh -c "apk add curl && geth --dev --dev.period 0 --rpc --rpcaddr 0.0.0.0 --rpcvhosts=* --rpcport=8545" 26 | -------------------------------------------------------------------------------- /docker-compose.datadog.yml: -------------------------------------------------------------------------------- 1 | version: "2.3" 2 | services: 3 | datadog: 4 | image: datadog/agent:latest 5 | restart: always 6 | environment: 7 | - DD_API_KEY=${DD_API_KEY} 8 | - DD_DOGSTATSD_NON_LOCAL_TRAFFIC=true 9 | - DD_LOG_LEVEL=debug 10 | - DOCKER_CONTENT_TRUST=1 11 | - DD_APM_ENABLED=true 12 | volumes: 13 | - /var/run/docker.sock:/var/run/docker.sock 14 | - /proc/:/host/proc/:ro 15 | - /sys/fs/cgroup:/host/sys/fs/cgroup:ro 16 | ports: 17 | - "2003-2004:2003-2004" 18 | - "2023-2024:2023-2024" 19 | - "8125:8125/udp" 20 | - "8126:8126/tcp" 21 | -------------------------------------------------------------------------------- /docker-compose.dev.yml: -------------------------------------------------------------------------------- 1 | version: "2.3" 2 | services: 3 | elixir-omg: 4 | image: omisegoimages/elixir-omg-builder:stable-20201207 5 | environment: 6 | DATABASE_URL: postgres://omisegodev:omisegodev@postgres:5432/omisego_dev 7 | TEST_DATABASE_URL: postgres://omisegodev:omisegodev@postgres:5432/omisego_test 8 | SHELL: /bin/bash 9 | volumes: 10 | - .:/app:rw 11 | depends_on: 12 | postgres: 13 | condition: service_healthy 14 | networks: 15 | chain_net: 16 | ipv4_address: 172.27.0.119 17 | watcher: 18 | environment: 19 | - DD_DISABLED=false 20 | depends_on: 21 | datadog: 22 | condition: service_healthy 23 | watcher_info: 24 | environment: 25 | - DD_DISABLED=false 26 | depends_on: 27 | datadog: 28 | condition: service_healthy 29 | childchain: 30 | environment: 31 | - DD_DISABLED=false 32 | depends_on: 33 | datadog: 34 | condition: service_healthy 35 | -------------------------------------------------------------------------------- /docker-compose.specs.yml: -------------------------------------------------------------------------------- 1 | # this is an override to our usual docker-compose.yml which enables cabbage integration tests to run against a 2 | # test-friendly setup of our services 3 | version: "2.3" 4 | services: 5 | watcher: 6 | environment: 7 | - EXIT_PROCESSOR_SLA_MARGIN=30 8 | watcher_info: 9 | environment: 10 | - EXIT_PROCESSOR_SLA_MARGIN=30 11 | -------------------------------------------------------------------------------- /docker/create_databases.sql: -------------------------------------------------------------------------------- 1 | CREATE USER feefeed; 2 | ALTER USER feefeed CREATEDB; 3 | ALTER USER feefeed WITH PASSWORD 'feefeed'; 4 | CREATE DATABASE feefeed; 5 | GRANT ALL PRIVILEGES ON DATABASE feefeed TO feefeed; 6 | 7 | CREATE USER engine_repo; 8 | ALTER USER engine_repo CREATEDB; 9 | ALTER USER engine_repo WITH PASSWORD 'engine_repo'; 10 | CREATE DATABASE engine_repo; 11 | GRANT ALL PRIVILEGES ON DATABASE engine_repo TO engine_repo; 12 | 13 | CREATE USER omisego_dev; 14 | ALTER USER omisego_dev CREATEDB; 15 | ALTER USER omisego_dev WITH PASSWORD 'omisego_dev'; 16 | CREATE DATABASE omisego_dev; 17 | GRANT ALL PRIVILEGES ON DATABASE omisego_dev TO omisego_dev; 18 | 19 | CREATE DATABASE omisego_test; 20 | GRANT ALL PRIVILEGES ON DATABASE omisego_test TO omisego_dev; 21 | -------------------------------------------------------------------------------- /docker/geth/command: -------------------------------------------------------------------------------- 1 | # Configures geth with the deployer and authority accounts. This includes: 2 | # 1. Configuring the deployer's keystore 3 | # 2. Configuring the authority's keystore 4 | # 3. Configuring the keystores' password 5 | # 4. Unlocking the accounts by their indexes 6 | # CAREFUL with --allow-insecure-unlock! 7 | # Starts geth 8 | # Websocket is not used by the applications but enabled for debugging/testing convenience 9 | geth \ 10 | --verbosity 0 \ 11 | --miner.gastarget 7500000 \ 12 | --nousb \ 13 | --miner.gasprice "10" \ 14 | --nodiscover \ 15 | --maxpeers 0 \ 16 | --datadir data/ \ 17 | --syncmode 'fast' \ 18 | --networkid 1337 \ 19 | --gasprice '1' \ 20 | --keystore ./data/geth/keystore/ \ 21 | --password /data/geth-blank-password \ 22 | --unlock "0,1" \ 23 | --rpc \ 24 | --rpcapi personal,web3,eth,net \ 25 | --rpcaddr 0.0.0.0 \ 26 | --rpcvhosts=* \ 27 | --rpcport=${RPC_PORT} \ 28 | --ws \ 29 | --wsaddr 0.0.0.0 \ 30 | --wsorigins='*' \ 31 | --mine \ 32 | --allow-insecure-unlock 33 | -------------------------------------------------------------------------------- /docker/geth/geth-blank-password: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omgnetwork/elixir-omg/2c68973d8f29033d137f63a6e060f12e2a7dcd59/docker/geth/geth-blank-password -------------------------------------------------------------------------------- /docker/nginx/geth_nginx.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | access_log off; 4 | location / { 5 | proxy_pass http://172.27.0.101:8545; 6 | } 7 | } 8 | 9 | server { 10 | listen 81; 11 | access_log off; 12 | location / { 13 | proxy_pass http://172.27.0.101:8546; 14 | proxy_http_version 1.1; 15 | proxy_set_header Upgrade $http_upgrade; 16 | proxy_set_header Connection "upgrade"; 17 | proxy_connect_timeout 7d; 18 | proxy_send_timeout 7d; 19 | proxy_read_timeout 7d; 20 | } 21 | } -------------------------------------------------------------------------------- /docker/nginx/nginx.conf: -------------------------------------------------------------------------------- 1 | user nginx; 2 | 3 | events { 4 | worker_connections 1000; 5 | } 6 | 7 | http { 8 | upstream childchain { 9 | server 172.27.0.103:9656; 10 | } 11 | 12 | server { 13 | listen 9656; 14 | access_log off; 15 | location / { 16 | proxy_pass http://childchain; 17 | 18 | proxy_next_upstream non_idempotent invalid_header error timeout http_500 http_502 http_504 http_403 http_404; 19 | fastcgi_read_timeout 10; 20 | proxy_read_timeout 10; 21 | 22 | error_page 504 502 =503 @empty; 23 | } 24 | 25 | location @empty { 26 | internal; 27 | return 200 ""; 28 | } 29 | } 30 | 31 | include "/etc/nginx/server_config/*.conf"; 32 | } 33 | 34 | include "/etc/nginx/main_config/*.conf"; -------------------------------------------------------------------------------- /docker/nginx/nginx.reorg.conf: -------------------------------------------------------------------------------- 1 | events {} 2 | http { 3 | upstream geth { 4 | server 172.27.0.201:8545; 5 | server 172.27.0.202:8545; 6 | } 7 | 8 | upstream websocket { 9 | server 172.27.0.201:8546; 10 | server 172.27.0.202:8546; 11 | } 12 | 13 | server { 14 | listen 80; 15 | 16 | location / { 17 | proxy_pass http://geth; 18 | proxy_next_upstream non_idempotent invalid_header error timeout http_500 http_502 http_504 http_403 http_404; 19 | proxy_next_upstream_tries 4; 20 | fastcgi_read_timeout 10; 21 | proxy_read_timeout 10; 22 | } 23 | } 24 | 25 | server { 26 | listen 81; 27 | 28 | location / { 29 | proxy_pass http://websocket; 30 | proxy_http_version 1.1; 31 | proxy_set_header Upgrade $http_upgrade; 32 | proxy_set_header Connection "upgrade"; 33 | proxy_next_upstream non_idempotent invalid_header error timeout http_500 http_502 http_504 http_403 http_404; 34 | proxy_connect_timeout 7d; 35 | proxy_send_timeout 7d; 36 | proxy_read_timeout 7d; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /docker/static_feefeed/file.json: -------------------------------------------------------------------------------- 1 | { 2 | "data":{ 3 | "1":{ 4 | "0x0000000000000000000000000000000000000000":{ 5 | "amount":1, 6 | "contract_address":"0x0000000000000000000000000000000000000000", 7 | "pair":"eth_eth", 8 | "pair_reversed":false, 9 | "pegged_amount":null, 10 | "pegged_currency":null, 11 | "pegged_subunit_to_unit":null, 12 | "subunit_to_unit":1000000000000000000, 13 | "symbol":"ETH", 14 | "type":"fixed", 15 | "updated_at":"2021-01-18T18:56:59.939198Z" 16 | }, 17 | "0xb1952c4e36d153a49eccc01a4d93b9ecbabb7208":{ 18 | "amount":414023614895550, 19 | "contract_address":"0xd26114cd6EE289AccF82350c8d8487fedB8A0C07", 20 | "pair":"omg_eth", 21 | "pair_reversed":false, 22 | "pegged_amount":0.33, 23 | "pegged_currency":"eth_gas", 24 | "pegged_subunit_to_unit":1000000000000000000, 25 | "subunit_to_unit":1000000000000000000, 26 | "symbol":"OMG", 27 | "type":"pegged", 28 | "updated_at":"2021-01-18T18:56:59.939198Z" 29 | } 30 | } 31 | }, 32 | "success":true, 33 | "version":"1" 34 | } -------------------------------------------------------------------------------- /docs/api_specs/index.html.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: OMG Network APIs Reference 3 | 4 | language_tabs: # must be one of https://git.io/vQNgJ 5 | - shell 6 | - elixir 7 | - javascript 8 | 9 | toc_footers: 10 | - Documentation Powered by Slate 11 | 12 | includes: 13 | - operator_api_specs 14 | - watcher_api_specs 15 | - info_api_specs 16 | - errors 17 | 18 | search: true 19 | --- 20 | 21 | # Introduction 22 | 23 | This is the HTTP-RPC API for the Child Chain Server and Watcher. 24 | 25 | All calls use HTTP POST and pass options in the request body in JSON format. 26 | Errors will usually return with HTTP response code 200, and the details of the error in the response body. 27 | See [Errors](#errors). 28 | -------------------------------------------------------------------------------- /docs/assets/OMG-network-eWallet.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omgnetwork/elixir-omg/2c68973d8f29033d137f63a6e060f12e2a7dcd59/docs/assets/OMG-network-eWallet.jpg -------------------------------------------------------------------------------- /docs/assets/architecture_overview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omgnetwork/elixir-omg/2c68973d8f29033d137f63a6e060f12e2a7dcd59/docs/assets/architecture_overview.jpg -------------------------------------------------------------------------------- /docs/assets/dex_design/01_ODEX Features.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omgnetwork/elixir-omg/2c68973d8f29033d137f63a6e060f12e2a7dcd59/docs/assets/dex_design/01_ODEX Features.png -------------------------------------------------------------------------------- /docs/assets/dex_design/02_Phase 1 - Technology Proof of Concept.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omgnetwork/elixir-omg/2c68973d8f29033d137f63a6e060f12e2a7dcd59/docs/assets/dex_design/02_Phase 1 - Technology Proof of Concept.png -------------------------------------------------------------------------------- /docs/assets/dex_design/03_Phase 2 - MVP.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omgnetwork/elixir-omg/2c68973d8f29033d137f63a6e060f12e2a7dcd59/docs/assets/dex_design/03_Phase 2 - MVP.png -------------------------------------------------------------------------------- /docs/assets/dex_design/04_Phase 3 - Bonded Exchages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omgnetwork/elixir-omg/2c68973d8f29033d137f63a6e060f12e2a7dcd59/docs/assets/dex_design/04_Phase 3 - Bonded Exchages.png -------------------------------------------------------------------------------- /docs/assets/dex_design/05_Phase 4 - Order Privacy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omgnetwork/elixir-omg/2c68973d8f29033d137f63a6e060f12e2a7dcd59/docs/assets/dex_design/05_Phase 4 - Order Privacy.png -------------------------------------------------------------------------------- /docs/assets/dex_design/06_OMG On-chain Venue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omgnetwork/elixir-omg/2c68973d8f29033d137f63a6e060f12e2a7dcd59/docs/assets/dex_design/06_OMG On-chain Venue.png -------------------------------------------------------------------------------- /docs/assets/dex_design/07_safety_considerations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omgnetwork/elixir-omg/2c68973d8f29033d137f63a6e060f12e2a7dcd59/docs/assets/dex_design/07_safety_considerations.png -------------------------------------------------------------------------------- /docs/assets/dex_design/08_ODEX Alternative State.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omgnetwork/elixir-omg/2c68973d8f29033d137f63a6e060f12e2a7dcd59/docs/assets/dex_design/08_ODEX Alternative State.png -------------------------------------------------------------------------------- /docs/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omgnetwork/elixir-omg/2c68973d8f29033d137f63a6e060f12e2a7dcd59/docs/assets/logo.png -------------------------------------------------------------------------------- /docs/run_local_watcher.md: -------------------------------------------------------------------------------- 1 | # Running your own Watcher locally 2 | 3 | The `docker-compose` tooling in the root of `elixir-omg` allows users to run their own instance of the Watcher to connect to the OMG Network and validate transactions. 4 | 5 | ### Requirements 6 | 7 | - Docker 8 | - `docker-compose` - known to work with `docker-compose version 1.24.0, build 0aa59064`, version `1.17` has had problems 9 | - Ethereum connectivity: local Ethereum node or Infura 10 | 11 | ### Startup 12 | 13 | 1) Add an ENV variable `INFURA_API_KEY` to your environment or override the ETHEREUM_RPC_URL completely in the `docker-compose-watcher.yml` file with the RPC connection information. 14 | 15 | 2) From the root of the `elixir-omg` execute: 16 | 17 | - `docker-compose -f docker-compose-watcher.yml up` 18 | 19 | Modify the other environment variables for connecting to other networks. 20 | -------------------------------------------------------------------------------- /dummy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omgnetwork/elixir-omg/2c68973d8f29033d137f63a6e060f12e2a7dcd59/dummy -------------------------------------------------------------------------------- /fees_setup.env: -------------------------------------------------------------------------------- 1 | FEE_CLAIMER_ADDRESS=0x3b9f4c1dd26e0be593373b1d36cee2008cbeb837 2 | FEE_FEED_URL=http://172.27.0.110:4000/api/v1 3 | STORED_FEE_UPDATE_INTERVAL_MINUTES=1 4 | FEE_CHANGE_TOLERANCE_PERCENT=1 5 | FEE_BUFFER_DURATION_MS=30000 6 | FEE_ADAPTER=file 7 | FEE_SPECS_FILE_PATH=/dev-artifacts/fee_specs.dev.json -------------------------------------------------------------------------------- /priv/dev-artifacts/README.md: -------------------------------------------------------------------------------- 1 | # Dev artifacts 2 | 3 | Contains various development artifacts that are useful for development environment configs but 4 | not to be used in production environments. 5 | 6 | For example: 7 | 8 | - `fee_specs.dev.json`: The fee specs used by docker-compose.yml which is only intended for development setup. 9 | -------------------------------------------------------------------------------- /priv/dev-artifacts/fee_specs.dev.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": { 3 | "0x0000000000000000000000000000000000000000": { 4 | "amount": 1, 5 | "pegged_amount": null, 6 | "pegged_currency": null, 7 | "pegged_subunit_to_unit": null, 8 | "subunit_to_unit": 1000000000000000000, 9 | "updated_at": "2019-01-01T10:10:00+00:00", 10 | "symbol": "ETH", 11 | "type": "fixed" 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /priv/dev-artifacts/fee_specs.test.json: -------------------------------------------------------------------------------- 1 | { 2 | } 3 | -------------------------------------------------------------------------------- /priv/perf/.formatter.exs: -------------------------------------------------------------------------------- 1 | # Used by "mix format" 2 | [ 3 | inputs: ["mix.exs", "config/*.exs"], 4 | line_length: 120, 5 | subdirectories: ["apps/*"] 6 | ] 7 | -------------------------------------------------------------------------------- /priv/perf/.gitignore: -------------------------------------------------------------------------------- 1 | # The directory Mix will write compiled artifacts to. 2 | /_build/ 3 | 4 | # If you run "mix test --cover", coverage assets end up here. 5 | /cover/ 6 | 7 | # The directory Mix downloads your dependencies sources to. 8 | /deps/ 9 | 10 | # Where third-party dependencies like ExDoc output generated docs. 11 | /doc/ 12 | 13 | # Ignore .fetch files in case you like to edit your project deps locally. 14 | /.fetch 15 | 16 | # If the VM crashes, it generates a dump, let's ignore it too. 17 | erl_crash.dump 18 | 19 | # Also ignore archive artifacts (built via "mix archive.build"). 20 | *.ez 21 | 22 | # Open api auto generated elixir client directories 23 | /apps/child_chain_api/ 24 | /apps/watcher_info_api/ 25 | /apps/watcher_security_critical_api/ 26 | 27 | # Load test results 28 | /results/ 29 | -------------------------------------------------------------------------------- /priv/perf/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: list 2 | 3 | COMPOSE_FULL_SERVICES=-f ../../docker-compose.yml -f ../../docker-compose.datadog.yml 4 | 5 | list: 6 | @$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$' 7 | 8 | clean: 9 | docker-compose $(COMPOSE_FULL_SERVICES) down && docker volume prune --force 10 | 11 | start-services: 12 | cd ../../ && \ 13 | SNAPSHOT=SNAPSHOT_MIX_EXIT_PERIOD_SECONDS_120 make init-contracts && \ 14 | cd priv/perf/ && \ 15 | docker-compose $(COMPOSE_FULL_SERVICES) up -d 16 | 17 | stop-services: 18 | docker-compose $(COMPOSE_FULL_SERVICES) down 19 | 20 | log-services: 21 | docker-compose $(COMPOSE_FULL_SERVICES) logs -f childchain feefeed watcher watcher_info geth 22 | 23 | init: 24 | . scripts/generate_api_client.sh 25 | mix deps.get 26 | 27 | test: # runs test against child chain and geth provided in test docker containers 28 | LOAD_TEST_FAUCET_PRIVATE_KEY=0xd885a307e35738f773d8c9c63c7a3f3977819274638d04aaf934a1e1158513ce mix test 29 | 30 | format-code-check-warnings: 31 | LOAD_TEST_FAUCET_PRIVATE_KEY=0xd885a307e35738f773d8c9c63c7a3f3977819274638d04aaf934a1e1158513ce MIX_ENV=test mix do compile --warnings-as-errors --ignore-module-conflict --force, test --exclude test 32 | -------------------------------------------------------------------------------- /priv/perf/apps/load_test/.formatter.exs: -------------------------------------------------------------------------------- 1 | # Used by "mix format" 2 | [ 3 | inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"], 4 | line_length: 120 5 | ] 6 | -------------------------------------------------------------------------------- /priv/perf/apps/load_test/.gitignore: -------------------------------------------------------------------------------- 1 | # The directory Mix will write compiled artifacts to. 2 | /_build/ 3 | 4 | # If you run "mix test --cover", coverage assets end up here. 5 | /cover/ 6 | 7 | # The directory Mix downloads your dependencies sources to. 8 | /deps/ 9 | 10 | # Where third-party dependencies like ExDoc output generated docs. 11 | /doc/ 12 | 13 | # Ignore .fetch files in case you like to edit your project deps locally. 14 | /.fetch 15 | 16 | # If the VM crashes, it generates a dump, let's ignore it too. 17 | erl_crash.dump 18 | 19 | # Also ignore archive artifacts (built via "mix archive.build"). 20 | *.ez 21 | 22 | # Ignore package tarball (built via "mix hex.build"). 23 | load_test-*.tar 24 | 25 | # Ignore Chaperon report outputs 26 | /results/ 27 | -------------------------------------------------------------------------------- /priv/perf/apps/load_test/README.md: -------------------------------------------------------------------------------- 1 | # LoadTest 2 | 3 | Load test is load test! 4 | -------------------------------------------------------------------------------- /priv/perf/apps/load_test/lib/child_chain/abi/abi_function_selector.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule LoadTest.ChildChain.Abi.AbiFunctionSelector do 16 | @moduledoc """ 17 | 18 | We define Solidity Function selectors that help us decode returned values from function calls 19 | """ 20 | # workaround for https://github.com/omgnetwork/elixir-omg/issues/1632 21 | def blocks() do 22 | %ABI.FunctionSelector{ 23 | function: "blocks", 24 | input_names: ["block_hash", "block_timestamp"], 25 | inputs_indexed: nil, 26 | method_id: <<242, 91, 63, 153>>, 27 | # returns: [bytes: 32, uint: 256], 28 | type: :function, 29 | # types: [uint: 256] 30 | types: [bytes: 32, uint: 256] 31 | } 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /priv/perf/apps/load_test/lib/connection/child_chain.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | defmodule LoadTest.Connection.ChildChain do 15 | @moduledoc """ 16 | Module that overrides the Tesla middleware with the url from config. 17 | """ 18 | 19 | alias LoadTest.Connection.ConnectionDefaults 20 | 21 | def client() do 22 | base_url = Application.fetch_env!(:load_test, :child_chain_url) 23 | middleware = [{Tesla.Middleware.BaseUrl, base_url} | ConnectionDefaults.middleware()] 24 | 25 | Tesla.client(middleware) 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /priv/perf/apps/load_test/lib/connection/watcher_info.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | defmodule LoadTest.Connection.WatcherInfo do 15 | @moduledoc """ 16 | Module that overrides the Tesla middleware with the url from config. 17 | """ 18 | 19 | alias LoadTest.Connection.ConnectionDefaults 20 | 21 | def client() do 22 | base_url = Application.fetch_env!(:load_test, :watcher_info_url) 23 | middleware = [{Tesla.Middleware.BaseUrl, base_url} | ConnectionDefaults.middleware()] 24 | 25 | Tesla.client(middleware) 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /priv/perf/apps/load_test/lib/connection/watcher_security.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | defmodule LoadTest.Connection.WatcherSecurity do 15 | @moduledoc """ 16 | Module that overrides the Tesla middleware with the url from config. 17 | """ 18 | 19 | alias LoadTest.Connection.ConnectionDefaults 20 | 21 | def client() do 22 | base_url = Application.fetch_env!(:load_test, :watcher_security_url) 23 | middleware = [{Tesla.Middleware.BaseUrl, base_url} | ConnectionDefaults.middleware()] 24 | 25 | Tesla.client(middleware) 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /priv/perf/apps/load_test/lib/ethereum/crypto.ex: -------------------------------------------------------------------------------- 1 | defmodule LoadTest.Ethereum.Crypto do 2 | @moduledoc """ 3 | Cryptography related utility functions 4 | """ 5 | @type hash_t() :: <<_::256>> 6 | @type priv_key_t :: <<_::256>> 7 | 8 | @doc """ 9 | Produces a KECCAK digest for the message. 10 | 11 | see https://hexdocs.pm/exth_crypto/ExthCrypto.Hash.html#kec/0 12 | """ 13 | @spec hash(binary) :: hash_t() 14 | def hash(message), do: elem(ExKeccak.hash_256(message), 1) 15 | 16 | @doc """ 17 | Generates private key. Internally uses OpenSSL RAND_bytes. May throw if there is not enough entropy. 18 | """ 19 | @spec generate_private_key() :: {:ok, priv_key_t()} 20 | def generate_private_key, do: {:ok, :crypto.strong_rand_bytes(32)} 21 | end 22 | -------------------------------------------------------------------------------- /priv/perf/apps/load_test/lib/runner/deposits.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule LoadTest.Runner.Deposits do 16 | @moduledoc """ 17 | Deposits tests runner. 18 | """ 19 | use Chaperon.LoadTest 20 | 21 | def scenarios do 22 | [ 23 | {{1, LoadTest.Scenario.Deposits}, %{}} 24 | ] 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /priv/perf/apps/load_test/lib/runner/smoke.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule LoadTest.Runner.Smoke do 16 | @moduledoc """ 17 | Smoke test to verify that the childchain, watcher and watcher-info are up and running 18 | 19 | Run with `mix test apps/load_test/test/load_tests/runner/smoke_test.exs` 20 | """ 21 | 22 | use Chaperon.LoadTest 23 | 24 | def scenarios do 25 | [ 26 | {{1, LoadTest.Scenario.Smoke}, %{}} 27 | ] 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /priv/perf/apps/load_test/lib/runner/transactions.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule LoadTest.Runner.Transactions do 16 | @moduledoc """ 17 | Transactions tests runner. 18 | """ 19 | use Chaperon.LoadTest 20 | 21 | def scenarios do 22 | [ 23 | {{1, LoadTest.Scenario.Transactions}, %{}} 24 | ] 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /priv/perf/apps/load_test/lib/scenario/start_standard_exit.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule LoadTest.Scenario.StartStandardExit do 16 | @moduledoc """ 17 | Starts a standard exit. 18 | 19 | ## configuration values 20 | - `exiter` the account that's starting the exit 21 | - `utxo` the utxo to exit 22 | """ 23 | 24 | use Chaperon.Scenario 25 | 26 | alias Chaperon.Session 27 | alias LoadTest.ChildChain.Exit 28 | 29 | def run(session) do 30 | exiter = config(session, [:exiter]) 31 | utxo = config(session, [:utxo]) 32 | gas_price = config(session, [:gas_price]) 33 | 34 | tx_hash = 35 | utxo 36 | |> Exit.wait_for_exit_data() 37 | |> Exit.start_exit(exiter, gas_price) 38 | 39 | Session.assign(session, tx_hash: tx_hash) 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /priv/perf/apps/load_test/lib/scenario/watcher_status.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule LoadTest.Scenario.WatcherStatus do 16 | @moduledoc """ 17 | Calls Watcher status.get 18 | """ 19 | use Chaperon.Scenario 20 | 21 | alias Chaperon.Session 22 | 23 | def run(session) do 24 | {:ok, response} = WatcherSecurityCriticalAPI.Api.Status.status_get(LoadTest.Connection.WatcherSecurity.client()) 25 | watcher_status = Jason.decode!(response.body) 26 | Session.assign(session, watcher_status: watcher_status) 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /priv/perf/apps/load_test/lib/service/sleeper.ex: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule LoadTest.Service.Sleeper do 16 | @moduledoc """ 17 | Sleeps the current process for the given timeout and print the given warning. 18 | """ 19 | 20 | require Logger 21 | 22 | @spec sleep(String.t()) :: :ok 23 | def sleep(message) do 24 | _ = Logger.info(message) 25 | Process.sleep(retry_sleep()) 26 | end 27 | 28 | defp retry_sleep() do 29 | Application.fetch_env!(:load_test, :retry_sleep) 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /priv/perf/apps/load_test/test/load_test/runner/childchain_test.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule LoadTest.Runner.ChildChainTest do 16 | @moduledoc """ 17 | child chain load test 18 | """ 19 | use ExUnit.Case 20 | 21 | @tag timeout: 6_000_000 22 | test "childchain test" do 23 | Chaperon.run_load_test(LoadTest.Runner.ChildChainTransactions, print_results: true) 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /priv/perf/apps/load_test/test/load_test/runner/smoke_test.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule LoadTest.Runner.SmokeTest do 16 | @moduledoc """ 17 | Runs a smoke test for the perf tests setup 18 | """ 19 | use ExUnit.Case 20 | 21 | test "smoke test" do 22 | Chaperon.run_load_test(LoadTest.Runner.Smoke, print_results: false) 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /priv/perf/apps/load_test/test/load_test/runner/standard_exit_test.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule LoadTest.Runner.StandardExitTest do 16 | @moduledoc """ 17 | Runs a smoke test for utxos load test 18 | """ 19 | use ExUnit.Case 20 | 21 | @tag timeout: 6_000_000 22 | test "should run standard exit load test" do 23 | Chaperon.run_load_test(LoadTest.Runner.StandardExits, print_results: true) 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /priv/perf/apps/load_test/test/load_test/runner/utxos_load_test.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule LoadTest.Runner.UtxosLoadTest do 16 | @moduledoc """ 17 | Runs a smoke test for utxos load test 18 | """ 19 | use ExUnit.Case 20 | 21 | @tag timeout: 6_000_000 22 | test "smoke test - should run utxos load test" do 23 | Chaperon.run_load_test(LoadTest.Runner.UtxosLoad, print_results: true) 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /priv/perf/apps/load_test/test/load_test/runner/watcher_info_test.exs: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2020 OMG Network Pte Ltd 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | defmodule LoadTest.Runner.WatcherInfoTest do 16 | @moduledoc """ 17 | watcher info load test 18 | """ 19 | use ExUnit.Case 20 | 21 | @tag timeout: 6_000_000 22 | test "watcher info test" do 23 | Chaperon.run_load_test(LoadTest.Runner.WatcherInfoAccountApi, print_results: true) 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /priv/perf/apps/load_test/test/test_helper.exs: -------------------------------------------------------------------------------- 1 | {:ok, _} = Application.ensure_all_started(:fake_server) 2 | 3 | ExUnit.start(exclude: [:skip]) 4 | -------------------------------------------------------------------------------- /priv/perf/config/dev.exs: -------------------------------------------------------------------------------- 1 | use Mix.Config 2 | -------------------------------------------------------------------------------- /priv/perf/config/stress.exs: -------------------------------------------------------------------------------- 1 | use Mix.Config 2 | 3 | # Target tps. 4 | # Note that this is only a rough estimate and depends on the response time from the childchain. 5 | # If the childchain is under high load, tps will drop. 6 | tps = 100 7 | 8 | # Must be >= than tps, _should_ be at least 2x tps 9 | concurrency = 200 10 | 11 | # Minutes that the test should run. 12 | # Again, a rough estimate - if the childchain is under high load the test will take longer to finish 13 | test_duration = 1 14 | 15 | tx_delay = trunc(concurrency / tps) * 1000 16 | tx_per_session = trunc(test_duration * 60 / trunc(tx_delay / 1000)) 17 | 18 | config :load_test, 19 | utxo_load_test_config: %{ 20 | concurrent_sessions: 1, 21 | utxos_to_create_per_session: 30, 22 | transactions_per_session: 4 23 | }, 24 | childchain_transactions_test_config: %{ 25 | concurrent_sessions: concurrency, 26 | transactions_per_session: tx_per_session, 27 | transaction_delay: tx_delay 28 | }, 29 | watcher_info_test_config: %{ 30 | concurrent_sessions: 100, 31 | iterations: 10, 32 | merge_scenario_sessions: true 33 | }, 34 | standard_exit_test_config: %{ 35 | concurrent_sessions: 1, 36 | exits_per_session: 10 37 | } 38 | -------------------------------------------------------------------------------- /priv/perf/config/test.exs: -------------------------------------------------------------------------------- 1 | use Mix.Config 2 | 3 | config :ethereumex, 4 | url: "http://localhost:8545" 5 | 6 | config :load_test, 7 | child_chain_url: "http://localhost:9656", 8 | watcher_security_url: "http://localhost:7434", 9 | watcher_info_url: "http://localhost:7534", 10 | faucet_deposit_amount: trunc(:math.pow(10, 18) * 10), 11 | # fee testing setup: https://github.com/omgnetwork/fee-rules-public/blob/master/fee_rules.json 12 | fee_amount: 75, 13 | utxo_load_test_config: %{ 14 | concurrent_sessions: 10, 15 | utxos_to_create_per_session: 5, 16 | transactions_per_session: 5 17 | }, 18 | childchain_transactions_test_config: %{ 19 | concurrent_sessions: 10, 20 | transactions_per_session: 10 21 | }, 22 | watcher_info_test_config: %{ 23 | concurrent_sessions: 2, 24 | iterations: 2, 25 | merge_scenario_sessions: true 26 | }, 27 | standard_exit_test_config: %{ 28 | concurrent_sessions: 1, 29 | exits_per_session: 4 30 | }, 31 | record_metrics: false 32 | -------------------------------------------------------------------------------- /priv/perf/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule Perf.MixProject do 2 | use Mix.Project 3 | 4 | def project do 5 | [ 6 | app: :perf, 7 | apps_path: "apps", 8 | start_permanent: Mix.env() == :prod, 9 | deps: deps() 10 | ] 11 | end 12 | 13 | defp deps do 14 | [ 15 | {:credo, "~> 1.5", only: [:dev, :test], runtime: false} 16 | ] 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /rel/env.sh.eex: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Sets and enables heart (recommended only in daemon mode) 4 | # case $RELEASE_COMMAND in 5 | # daemon*) 6 | # HEART_COMMAND="$RELEASE_ROOT/bin/$RELEASE_NAME $RELEASE_COMMAND" 7 | # export HEART_COMMAND 8 | # export ELIXIR_ERL_OPTIONS="-heart" 9 | # ;; 10 | # *) 11 | # ;; 12 | # esac 13 | 14 | # Set the release to work across nodes. If using the long name format like 15 | # the one below (my_app@127.0.0.1), you need to also uncomment the 16 | # RELEASE_DISTRIBUTION variable below. Must be "sname", "name" or "none". 17 | export RELEASE_DISTRIBUTION=name 18 | export RELEASE_NODE=<%= @release.name %>@$NODE_HOST 19 | -------------------------------------------------------------------------------- /snapshot_reorg.env: -------------------------------------------------------------------------------- 1 | SNAPSHOT=https://storage.googleapis.com/circleci-docker-artifacts/data-elixir-omg-tester-plasma-deployer-dev-10cafba-MIN_EXIT_PERIOD-120-PLASMA_CONTRACTS_SHA-a69c763f239b81c5eb46b0bbdef3459f764360dc-reorg.tar.gz 2 | CONTRACT_SHA=a69c763f239b81c5eb46b0bbdef3459f764360dc -------------------------------------------------------------------------------- /snapshots.env: -------------------------------------------------------------------------------- 1 | SNAPSHOT_MIX_EXIT_PERIOD_SECONDS_20=https://storage.googleapis.com/circleci-docker-artifacts/data-elixir-omg-tester-plasma-deployer-stable-20201207-MIN_EXIT_PERIOD-20-PLASMA_CONTRACTS_SHA-b3a5c8d5232edfab8617f6939733b08b67863c8a.tar.gz 2 | SNAPSHOT_MIX_EXIT_PERIOD_SECONDS_120=https://storage.googleapis.com/circleci-docker-artifacts/data-elixir-omg-tester-plasma-deployer-stable-20201207-MIN_EXIT_PERIOD-120-PLASMA_CONTRACTS_SHA-b3a5c8d5232edfab8617f6939733b08b67863c8a.tar.gz 3 | SNAPSHOT_MIX_EXIT_PERIOD_SECONDS_240=https://storage.googleapis.com/circleci-docker-artifacts/data-elixir-omg-tester-plasma-deployer-stable-20201207-MIN_EXIT_PERIOD-240-PLASMA_CONTRACTS_SHA-b3a5c8d5232edfab8617f6939733b08b67863c8a.tar.gz 4 | CONTRACT_SHA=b3a5c8d5232edfab8617f6939733b08b67863c8a 5 | --------------------------------------------------------------------------------