Merge pull request #7014 from blockscout/vb-spell-checking

Fix spell in namings, add spell checking in CI
pull/7026/head
Victor Baranov 2 years ago committed by GitHub
commit 80032449d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 46
      .github/workflows/config.yml
  2. 29
      CHANGELOG.md
  3. 1
      apps/block_scout_web/assets/__tests__/lib/smart_contract/common_helpers.js
  4. 2
      apps/block_scout_web/assets/css/theme/_dark-theme.scss
  5. 2
      apps/block_scout_web/assets/js/lib/async_listing_load.js
  6. 2
      apps/block_scout_web/assets/js/lib/queue.js
  7. 2
      apps/block_scout_web/assets/js/lib/random_access_pagination.js
  8. 6
      apps/block_scout_web/assets/js/lib/smart_contract/common_helpers.js
  9. 2
      apps/block_scout_web/assets/js/lib/smart_contract/connect.js
  10. 4
      apps/block_scout_web/lib/block_scout_web/chain.ex
  11. 2
      apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/contract_controller.ex
  12. 2
      apps/block_scout_web/lib/block_scout_web/controllers/api/v2/main_page_controller.ex
  13. 12
      apps/block_scout_web/lib/block_scout_web/controllers/api/v2/transaction_controller.ex
  14. 8
      apps/block_scout_web/lib/block_scout_web/etherscan.ex
  15. 2
      apps/block_scout_web/lib/block_scout_web/paging_helper.ex
  16. 2
      apps/block_scout_web/lib/block_scout_web/smart_contracts_api_v2_router.ex
  17. 2
      apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification_common_fields/_yul_contracts_switcher.html.eex
  18. 2
      apps/block_scout_web/lib/block_scout_web/templates/address_logs/_logs.html.eex
  19. 2
      apps/block_scout_web/lib/block_scout_web/templates/transaction_log/_logs.html.eex
  20. 2
      apps/block_scout_web/lib/block_scout_web/templates/verified_contracts/_contract.html.eex
  21. 2
      apps/block_scout_web/lib/block_scout_web/templates/verified_contracts/_metatags.html.eex
  22. 4
      apps/block_scout_web/lib/block_scout_web/views/api/v2/smart_contract_view.ex
  23. 4
      apps/block_scout_web/lib/block_scout_web/views/form_view.ex
  24. 12
      apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex
  25. 20
      apps/block_scout_web/priv/gettext/default.pot
  26. 20
      apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po
  27. 2
      apps/block_scout_web/test/block_scout_web/chain_test.exs
  28. 90
      apps/block_scout_web/test/block_scout_web/controllers/account/api/v1/user_controller_test.exs
  29. 2
      apps/block_scout_web/test/block_scout_web/controllers/api/v1/decompiled_smart_contract_controller_test.exs
  30. 24
      apps/block_scout_web/test/block_scout_web/controllers/api/v2/address_controller_test.exs
  31. 2
      apps/block_scout_web/test/block_scout_web/controllers/api/v2/main_page_controller_test.exs
  32. 6
      apps/block_scout_web/test/block_scout_web/controllers/api/v2/token_controller_test.exs
  33. 2
      apps/block_scout_web/test/block_scout_web/features/address_contract_verification_test.exs
  34. 2
      apps/block_scout_web/test/block_scout_web/features/viewing_transactions_test.exs
  35. 2
      apps/block_scout_web/test/block_scout_web/schema/query/address_test.exs
  36. 2
      apps/block_scout_web/test/block_scout_web/schema/query/token_transfers_test.exs
  37. 2
      apps/block_scout_web/test/block_scout_web/schema/query/transaction_test.exs
  38. 2
      apps/block_scout_web/test/block_scout_web/views/transaction_view_test.exs
  39. 2
      apps/ethereum_jsonrpc/lib/ethereum_jsonrpc.ex
  40. 2
      apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/log.ex
  41. 2
      apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/pending_transaction.ex
  42. 4
      apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/request_coordinator.ex
  43. 2
      apps/ethereum_jsonrpc/test/ethereum_jsonrpc/rolling_window_test.exs
  44. 2
      apps/ethereum_jsonrpc/test/ethereum_jsonrpc_test.exs
  45. 10
      apps/explorer/lib/explorer/account/tag_address.ex
  46. 10
      apps/explorer/lib/explorer/account/tag_transaction.ex
  47. 2
      apps/explorer/lib/explorer/account/watchlist_notification.ex
  48. 22
      apps/explorer/lib/explorer/chain.ex
  49. 2
      apps/explorer/lib/explorer/chain/address/coin_balance_daily.ex
  50. 2
      apps/explorer/lib/explorer/chain/address/token_balance.ex
  51. 2
      apps/explorer/lib/explorer/chain/cache/accounts.ex
  52. 2
      apps/explorer/lib/explorer/chain/cache/address_sum.ex
  53. 2
      apps/explorer/lib/explorer/chain/cache/address_sum_minus_burnt.ex
  54. 2
      apps/explorer/lib/explorer/chain/cache/block.ex
  55. 6
      apps/explorer/lib/explorer/chain/cache/gas_price_oracle.ex
  56. 2
      apps/explorer/lib/explorer/chain/cache/gas_usage.ex
  57. 2
      apps/explorer/lib/explorer/chain/cache/net_version.ex
  58. 2
      apps/explorer/lib/explorer/chain/cache/new_verified_contracts_counter.ex
  59. 2
      apps/explorer/lib/explorer/chain/cache/transaction.ex
  60. 2
      apps/explorer/lib/explorer/chain/import/runner.ex
  61. 4
      apps/explorer/lib/explorer/chain/import/runner/address/current_token_balances.ex
  62. 2
      apps/explorer/lib/explorer/chain/import/runner/address/token_balances.ex
  63. 4
      apps/explorer/lib/explorer/chain/import/runner/blocks.ex
  64. 2
      apps/explorer/lib/explorer/chain/import/runner/internal_transactions.ex
  65. 4
      apps/explorer/lib/explorer/chain/internal_transaction.ex
  66. 2
      apps/explorer/lib/explorer/chain/map_cache.ex
  67. 4
      apps/explorer/lib/explorer/chain/ordered_cache.ex
  68. 8
      apps/explorer/lib/explorer/chain/smart_contract.ex
  69. 2
      apps/explorer/lib/explorer/chain/smart_contract/verification_status.ex
  70. 4
      apps/explorer/lib/explorer/chain/supply/rsk.ex
  71. 2
      apps/explorer/lib/explorer/chain/token.ex
  72. 8
      apps/explorer/lib/explorer/chain/transaction.ex
  73. 2
      apps/explorer/lib/explorer/chain/transaction/history/historian.ex
  74. 2
      apps/explorer/lib/explorer/env_var_translator.ex
  75. 2
      apps/explorer/lib/explorer/repo/config_helper.ex
  76. 12
      apps/explorer/lib/explorer/smart_contract/reader.ex
  77. 16
      apps/explorer/lib/explorer/smart_contract/rust_verifier_interface.ex
  78. 10
      apps/explorer/lib/explorer/smart_contract/sig_provider_interface.ex
  79. 12
      apps/explorer/lib/explorer/smart_contract/solidity/publish_helper.ex
  80. 32
      apps/explorer/lib/explorer/smart_contract/solidity/publisher.ex
  81. 10
      apps/explorer/lib/explorer/smart_contract/solidity/verifier.ex
  82. 4
      apps/explorer/lib/explorer/validator/metadata_retriever.ex
  83. 10
      apps/explorer/lib/explorer/visualize/sol2uml.ex
  84. 2
      apps/explorer/test/explorer/account/notify/notify_test.exs
  85. 2
      apps/explorer/test/explorer/admin/administrator/role_test.exs
  86. 2
      apps/explorer/test/explorer/chain/events/publisher_test.exs
  87. 2
      apps/explorer/test/explorer/chain/import/runner/blocks_test.exs
  88. 4
      apps/explorer/test/explorer/chain/smart_contract_test.exs
  89. 2
      apps/explorer/test/explorer/chain/transaction_test.exs
  90. 2
      apps/explorer/test/explorer/chain_spec/parity/importer_test.exs
  91. 2
      apps/explorer/test/explorer/chain_test.exs
  92. 2
      apps/explorer/test/explorer/graphql_test.exs
  93. 18
      apps/explorer/test/explorer/smart_contract/solidity/code_compiler_test.exs
  94. 4
      apps/explorer/test/explorer/smart_contract/solidity/publisher_test.exs
  95. 32
      apps/explorer/test/explorer/smart_contract/solidity/verifier_test.exs
  96. 2
      apps/explorer/test/support/factory.ex
  97. 2
      apps/indexer/README.md
  98. 6
      apps/indexer/lib/indexer/fetcher/coin_balance_on_demand.ex
  99. 2
      apps/indexer/lib/indexer/fetcher/internal_transaction.ex
  100. 4
      apps/indexer/lib/indexer/fetcher/token_balance_on_demand.ex
  101. Some files were not shown because too many files have changed in this diff Show More

@ -223,6 +223,52 @@ jobs:
- name: Scan block_scout_web for vulnerabilities - name: Scan block_scout_web for vulnerabilities
run: mix sobelow --config run: mix sobelow --config
working-directory: "apps/block_scout_web" working-directory: "apps/block_scout_web"
cspell:
name: Check spelling
runs-on: ubuntu-latest
needs: build-and-cache
steps:
- uses: actions/checkout@v2
- uses: erlef/setup-beam@v1
with:
otp-version: ${{ env.OTP_VERSION }}
elixir-version: ${{ env.ELIXIR_VERSION }}
- name: Mix Deps Cache
uses: actions/cache@v2
id: deps-cache
with:
path: |
deps
_build
key: ${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-mixlockhash_14-${{ hashFiles('mix.lock') }}
restore-keys: |
${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-"
- name: Restore Explorer NPM Cache
uses: actions/cache@v2
id: explorer-npm-cache
with:
path: apps/explorer/node_modules
key: ${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-explorer-npm-${{ hashFiles('apps/explorer/package-lock.json') }}
restore-keys: |
${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-explorer-npm-
- name: Restore Blockscout Web NPM Cache
uses: actions/cache@v2
id: blockscoutweb-npm-cache
with:
path: apps/block_scout_web/assets/node_modules
key: ${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-blockscoutweb-npm-${{ hashFiles('apps/block_scout_web/assets/package-lock.json') }}
restore-keys: |
${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-blockscoutweb-npm-
- name: Run cspell
uses: streetsidesoftware/cspell-action@v2
with:
files: "**/*.ex* **/*.eex **/*.js"
eslint: eslint:
name: ESLint name: ESLint
runs-on: ubuntu-latest runs-on: ubuntu-latest

@ -12,6 +12,7 @@
### Chore ### Chore
- [#7014](https://github.com/blockscout/blockscout/pull/7014) - Fix spell in namings, add spell checking in CI
- [#7012](https://github.com/blockscout/blockscout/pull/7012) - Refactor socket.js - [#7012](https://github.com/blockscout/blockscout/pull/7012) - Refactor socket.js
- [#6960](https://github.com/blockscout/blockscout/pull/6960) - Add deploy + workflow for testing (bs-indexers-ethereum-goerli) - [#6960](https://github.com/blockscout/blockscout/pull/6960) - Add deploy + workflow for testing (bs-indexers-ethereum-goerli)
- [#6989](https://github.com/blockscout/blockscout/pull/6989) - Update bitwalker/alpine-elixir-phoenix: 1.13 -> 1.14 - [#6989](https://github.com/blockscout/blockscout/pull/6989) - Update bitwalker/alpine-elixir-phoenix: 1.13 -> 1.14
@ -177,7 +178,7 @@
- [#6401](https://github.com/blockscout/blockscout/pull/6401) - Add Sol2Uml contract visualization - [#6401](https://github.com/blockscout/blockscout/pull/6401) - Add Sol2Uml contract visualization
- [#6583](https://github.com/blockscout/blockscout/pull/6583), [#6687](https://github.com/blockscout/blockscout/pull/6687) - Missing ranges collector - [#6583](https://github.com/blockscout/blockscout/pull/6583), [#6687](https://github.com/blockscout/blockscout/pull/6687) - Missing ranges collector
- [#6574](https://github.com/blockscout/blockscout/pull/6574), [#6601](https://github.com/blockscout/blockscout/pull/6601) - Allow and manage insecure HTTP connection to the archive node - [#6574](https://github.com/blockscout/blockscout/pull/6574), [#6601](https://github.com/blockscout/blockscout/pull/6601) - Allow and manage insecure HTTP connection to the archive node
- [#6433](https://github.com/blockscout/blockscout/pull/6433), [#6698](https://github.com/blockscout/blockscout/pull/6698) - Update error pagess - [#6433](https://github.com/blockscout/blockscout/pull/6433), [#6698](https://github.com/blockscout/blockscout/pull/6698) - Update error pages
- [#6544](https://github.com/blockscout/blockscout/pull/6544) - API improvements - [#6544](https://github.com/blockscout/blockscout/pull/6544) - API improvements
- [#5561](https://github.com/blockscout/blockscout/pull/5561), [#6523](https://github.com/blockscout/blockscout/pull/6523), [#6549](https://github.com/blockscout/blockscout/pull/6549) - Improve working with contracts implementations - [#5561](https://github.com/blockscout/blockscout/pull/5561), [#6523](https://github.com/blockscout/blockscout/pull/6523), [#6549](https://github.com/blockscout/blockscout/pull/6549) - Improve working with contracts implementations
- [#6481](https://github.com/blockscout/blockscout/pull/6481) - Smart contract verification improvements - [#6481](https://github.com/blockscout/blockscout/pull/6481) - Smart contract verification improvements
@ -223,7 +224,7 @@
- [#6158](https://github.com/blockscout/blockscout/pull/6158) - Add missing clause for merge_twin_vyper_contract_with_changeset function - [#6158](https://github.com/blockscout/blockscout/pull/6158) - Add missing clause for merge_twin_vyper_contract_with_changeset function
- [#6090](https://github.com/blockscout/blockscout/pull/6090) - Fix metadata fetching for ERC-1155 tokens instances - [#6090](https://github.com/blockscout/blockscout/pull/6090) - Fix metadata fetching for ERC-1155 tokens instances
- [#6091](https://github.com/blockscout/blockscout/pull/6091) - Improve fetching media type for NFT - [#6091](https://github.com/blockscout/blockscout/pull/6091) - Improve fetching media type for NFT
- [#6094](https://github.com/blockscout/blockscout/pull/6094) - Fix inconsistent behaviour of `getsourcecode` method - [#6094](https://github.com/blockscout/blockscout/pull/6094) - Fix inconsistent behavior of `getsourcecode` method
- [#6105](https://github.com/blockscout/blockscout/pull/6105) - Fix some token transfers broadcasting - [#6105](https://github.com/blockscout/blockscout/pull/6105) - Fix some token transfers broadcasting
- [#6106](https://github.com/blockscout/blockscout/pull/6106) - Fix 500 response on `/coin-balance` for empty address - [#6106](https://github.com/blockscout/blockscout/pull/6106) - Fix 500 response on `/coin-balance` for empty address
- [#6118](https://github.com/blockscout/blockscout/pull/6118) - Fix unfetched token balances - [#6118](https://github.com/blockscout/blockscout/pull/6118) - Fix unfetched token balances
@ -643,7 +644,7 @@
- [#5656](https://github.com/blockscout/blockscout/pull/5656) - Gas price oracle - [#5656](https://github.com/blockscout/blockscout/pull/5656) - Gas price oracle
- [#5613](https://github.com/blockscout/blockscout/pull/5613) - Exchange rates CoinMarketCap source module - [#5613](https://github.com/blockscout/blockscout/pull/5613) - Exchange rates CoinMarketCap source module
- [#5588](https://github.com/blockscout/blockscout/pull/5588) - Add broadcasting of coin balance - [#5588](https://github.com/blockscout/blockscout/pull/5588) - Add broadcasting of coin balance
- [#5560](https://github.com/blockscout/blockscout/pull/5560) - Manual fetch benefeciaries - [#5560](https://github.com/blockscout/blockscout/pull/5560) - Manual fetch beneficiaries
- [#5479](https://github.com/blockscout/blockscout/pull/5479) - Remake of solidity verifier module; Verification UX improvements - [#5479](https://github.com/blockscout/blockscout/pull/5479) - Remake of solidity verifier module; Verification UX improvements
- [#5540](https://github.com/blockscout/blockscout/pull/5540) - Tx page: scroll to selected tab's data - [#5540](https://github.com/blockscout/blockscout/pull/5540) - Tx page: scroll to selected tab's data
@ -831,7 +832,7 @@
### Features ### Features
- [#5030](https://github.com/blockscout/blockscout/pull/5030) - API rate limiting - [#5030](https://github.com/blockscout/blockscout/pull/5030) - API rate limiting
- [#4924](https://github.com/blockscout/blockscout/pull/4924) - Add daily bytecode verifcation to prevent metamorphic contracts vulnerablity - [#4924](https://github.com/blockscout/blockscout/pull/4924) - Add daily bytecode verification to prevent metamorphic contracts vulnerability
- [#4908](https://github.com/blockscout/blockscout/pull/4908) - Add verification via standard JSON input - [#4908](https://github.com/blockscout/blockscout/pull/4908) - Add verification via standard JSON input
- [#5004](https://github.com/blockscout/blockscout/pull/5004) - Add ability to set up a separate DB endpoint for the API endpoints - [#5004](https://github.com/blockscout/blockscout/pull/5004) - Add ability to set up a separate DB endpoint for the API endpoints
- [#4989](https://github.com/blockscout/blockscout/pull/4989), [#4991](https://github.com/blockscout/blockscout/pull/4991) - Bridged tokens list API endpoint - [#4989](https://github.com/blockscout/blockscout/pull/4989), [#4991](https://github.com/blockscout/blockscout/pull/4991) - Bridged tokens list API endpoint
@ -841,7 +842,7 @@
- [#5045](https://github.com/blockscout/blockscout/pull/5045) - Contracts interaction improvements - [#5045](https://github.com/blockscout/blockscout/pull/5045) - Contracts interaction improvements
- [#5032](https://github.com/blockscout/blockscout/pull/5032) - Fix token transfer csv export - [#5032](https://github.com/blockscout/blockscout/pull/5032) - Fix token transfer csv export
- [#5020](https://github.com/blockscout/blockscout/pull/5020) - Token instance image display imrovement - [#5020](https://github.com/blockscout/blockscout/pull/5020) - Token instance image display improvement
- [#5019](https://github.com/blockscout/blockscout/pull/5019) - Fix fetch_last_token_balance function termination - [#5019](https://github.com/blockscout/blockscout/pull/5019) - Fix fetch_last_token_balance function termination
- [#5011](https://github.com/blockscout/blockscout/pull/5011) - Fix `0x0` implementation address - [#5011](https://github.com/blockscout/blockscout/pull/5011) - Fix `0x0` implementation address
- [#5008](https://github.com/blockscout/blockscout/pull/5008) - Extend decimals cap in format_according_to_decimals up to 24 - [#5008](https://github.com/blockscout/blockscout/pull/5008) - Extend decimals cap in format_according_to_decimals up to 24
@ -855,7 +856,7 @@
- [#4945](https://github.com/blockscout/blockscout/pull/4945) - Fix `Verify & Publish` button link - [#4945](https://github.com/blockscout/blockscout/pull/4945) - Fix `Verify & Publish` button link
- [#4938](https://github.com/blockscout/blockscout/pull/4938) - Fix displaying of nested arrays for contracts read - [#4938](https://github.com/blockscout/blockscout/pull/4938) - Fix displaying of nested arrays for contracts read
- [#4888](https://github.com/blockscout/blockscout/pull/4888) - Fix fetch_top_tokens method: add nulls last for token holders desc order - [#4888](https://github.com/blockscout/blockscout/pull/4888) - Fix fetch_top_tokens method: add nulls last for token holders desc order
- [#4867](https://github.com/blockscout/blockscout/pull/4867) - Fix bug in quering contracts method and improve contracts interactions - [#4867](https://github.com/blockscout/blockscout/pull/4867) - Fix bug in querying contracts method and improve contracts interactions
### Chore ### Chore
@ -965,13 +966,13 @@
- [#4569](https://github.com/blockscout/blockscout/pull/4569) - Smart-Contract: remove comment with the submission date - [#4569](https://github.com/blockscout/blockscout/pull/4569) - Smart-Contract: remove comment with the submission date
- [#4568](https://github.com/blockscout/blockscout/pull/4568) - TX page: Token transfer and minting section improvements - [#4568](https://github.com/blockscout/blockscout/pull/4568) - TX page: Token transfer and minting section improvements
- [#4540](https://github.com/blockscout/blockscout/pull/4540) - Allign copy buttons for `Block Details` and `Transaction Details` pages - [#4540](https://github.com/blockscout/blockscout/pull/4540) - Align copy buttons for `Block Details` and `Transaction Details` pages
- [#4528](https://github.com/blockscout/blockscout/pull/4528) - Block Details page: rework view - [#4528](https://github.com/blockscout/blockscout/pull/4528) - Block Details page: rework view
- [#4531](https://github.com/blockscout/blockscout/pull/4531) - Add Arbitrum support - [#4531](https://github.com/blockscout/blockscout/pull/4531) - Add Arbitrum support
- [#4524](https://github.com/blockscout/blockscout/pull/4524) - Add index position of transaction in the block - [#4524](https://github.com/blockscout/blockscout/pull/4524) - Add index position of transaction in the block
- [#4489](https://github.com/blockscout/blockscout/pull/4489) - Search results page - [#4489](https://github.com/blockscout/blockscout/pull/4489) - Search results page
- [#4475](https://github.com/blockscout/blockscout/pull/4475) - Tx page facelifting - [#4475](https://github.com/blockscout/blockscout/pull/4475) - Tx page facelifting
- [#4452](https://github.com/blockscout/blockscout/pull/4452) - Add names for smart-conrtact's function response - [#4452](https://github.com/blockscout/blockscout/pull/4452) - Add names for smart-contract's function response
### Fixes ### Fixes
@ -995,7 +996,7 @@
### Chore ### Chore
- [#4550](https://github.com/blockscout/blockscout/pull/4550) - Update con_cache package to 1.0 - [#4550](https://github.com/blockscout/blockscout/pull/4550) - Update con_cache package to 1.0
- [#4523](https://github.com/blockscout/blockscout/pull/4523) - Change order of transations in block's view - [#4523](https://github.com/blockscout/blockscout/pull/4523) - Change order of transactions in block's view
- [#4521](https://github.com/blockscout/blockscout/pull/4521) - Rewrite transaction page tooltips - [#4521](https://github.com/blockscout/blockscout/pull/4521) - Rewrite transaction page tooltips
- [#4516](https://github.com/blockscout/blockscout/pull/4516) - Add DB migrations step into Docker start script - [#4516](https://github.com/blockscout/blockscout/pull/4516) - Add DB migrations step into Docker start script
- [#4497](https://github.com/blockscout/blockscout/pull/4497) - Handle error in fetch_validators_list method - [#4497](https://github.com/blockscout/blockscout/pull/4497) - Handle error in fetch_validators_list method
@ -1020,7 +1021,7 @@
- [#4418](https://github.com/blockscout/blockscout/pull/4418) - Fix empty search results for the full-word search criteria - [#4418](https://github.com/blockscout/blockscout/pull/4418) - Fix empty search results for the full-word search criteria
- [#4406](https://github.com/blockscout/blockscout/pull/4406) - Fix internal server error on the validator's txs page - [#4406](https://github.com/blockscout/blockscout/pull/4406) - Fix internal server error on the validator's txs page
- [#4360](https://github.com/blockscout/blockscout/pull/4360) - Fix false-pending transactions in reorg blocks - [#4360](https://github.com/blockscout/blockscout/pull/4360) - Fix false-pending transactions in reorg blocks
- [#4388](https://github.com/blockscout/blockscout/pull/4388) - Fix internal server error on contract page for insctances without sourcify envs - [#4388](https://github.com/blockscout/blockscout/pull/4388) - Fix internal server error on contract page for instances without sourcify envs
- [#4385](https://github.com/blockscout/blockscout/pull/4385) - Fix html template for transaction's input; Add copy text for tuples - [#4385](https://github.com/blockscout/blockscout/pull/4385) - Fix html template for transaction's input; Add copy text for tuples
### Chore ### Chore
@ -1063,7 +1064,7 @@
- [#4295](https://github.com/blockscout/blockscout/pull/4295) - Mobile view fix: transaction tile tx hash overflow - [#4295](https://github.com/blockscout/blockscout/pull/4295) - Mobile view fix: transaction tile tx hash overflow
- [#4294](https://github.com/blockscout/blockscout/pull/4294) - User wont be able to open verification pages for verified smart-contract - [#4294](https://github.com/blockscout/blockscout/pull/4294) - User wont be able to open verification pages for verified smart-contract
- [#4240](https://github.com/blockscout/blockscout/pull/4240) - `[]` is accepted in write contract page - [#4240](https://github.com/blockscout/blockscout/pull/4240) - `[]` is accepted in write contract page
- [#4236](https://github.com/blockscout/blockscout/pull/4236), [#4242](https://github.com/blockscout/blockscout/pull/4242) - Fix typo, constructor instead of contructor - [#4236](https://github.com/blockscout/blockscout/pull/4236), [#4242](https://github.com/blockscout/blockscout/pull/4242) - Fix typo, constructor instead of constructor
- [#4167](https://github.com/blockscout/blockscout/pull/4167) - Deduplicate block numbers in acquire_blocks function - [#4167](https://github.com/blockscout/blockscout/pull/4167) - Deduplicate block numbers in acquire_blocks function
- [#4149](https://github.com/blockscout/blockscout/pull/4149) - Exclude smart_contract_additional_sources from JSON encoding in address schema - [#4149](https://github.com/blockscout/blockscout/pull/4149) - Exclude smart_contract_additional_sources from JSON encoding in address schema
- [#4137](https://github.com/blockscout/blockscout/pull/4137) - Get token balance query improvement - [#4137](https://github.com/blockscout/blockscout/pull/4137) - Get token balance query improvement
@ -2051,7 +2052,7 @@ fixed menu hovers in dark mode desktop view
- [#2036](https://github.com/blockscout/blockscout/pull/2036) - New tables for staking pools and delegators - [#2036](https://github.com/blockscout/blockscout/pull/2036) - New tables for staking pools and delegators
- [#1974](https://github.com/blockscout/blockscout/pull/1974) - feat: previous page button logic - [#1974](https://github.com/blockscout/blockscout/pull/1974) - feat: previous page button logic
- [#1999](https://github.com/blockscout/blockscout/pull/1999) - load data async on addresses page - [#1999](https://github.com/blockscout/blockscout/pull/1999) - load data async on addresses page
- [#1807](https://github.com/blockscout/blockscout/pull/1807) - New theming capabilites. - [#1807](https://github.com/blockscout/blockscout/pull/1807) - New theming capabilities.
- [#2040](https://github.com/blockscout/blockscout/pull/2040) - Verification links to other explorers for ETH - [#2040](https://github.com/blockscout/blockscout/pull/2040) - Verification links to other explorers for ETH
- [#2037](https://github.com/blockscout/blockscout/pull/2037) - add address logs search functionality - [#2037](https://github.com/blockscout/blockscout/pull/2037) - add address logs search functionality
- [#2012](https://github.com/blockscout/blockscout/pull/2012) - make all pages pagination async - [#2012](https://github.com/blockscout/blockscout/pull/2012) - make all pages pagination async
@ -2098,7 +2099,7 @@ fixed menu hovers in dark mode desktop view
- [#2014](https://github.com/blockscout/blockscout/pull/2014) - fix: use better queries for listLogs endpoint - [#2014](https://github.com/blockscout/blockscout/pull/2014) - fix: use better queries for listLogs endpoint
- [#2027](https://github.com/blockscout/blockscout/pull/2027) - fix: `BlocksTransactionsMismatch` ignoring blocks without transactions - [#2027](https://github.com/blockscout/blockscout/pull/2027) - fix: `BlocksTransactionsMismatch` ignoring blocks without transactions
- [#2070](https://github.com/blockscout/blockscout/pull/2070) - reduce `max_concurrency` of `BlocksTransactionsMismatch` fetcher - [#2070](https://github.com/blockscout/blockscout/pull/2070) - reduce `max_concurrency` of `BlocksTransactionsMismatch` fetcher
- [#2083](https://github.com/blockscout/blockscout/pull/2083) - allow total_difficuly to be nil - [#2083](https://github.com/blockscout/blockscout/pull/2083) - allow total_difficulty to be nil
- [#2086](https://github.com/blockscout/blockscout/pull/2086) - fix geth's staticcall without output - [#2086](https://github.com/blockscout/blockscout/pull/2086) - fix geth's staticcall without output
### Chore ### Chore
@ -2175,7 +2176,7 @@ Reverting of synchronous block counter, implemented in #1848
### Chore ### Chore
- [#1814](https://github.com/blockscout/blockscout/pull/1814) - Clear build artefacts script - [#1814](https://github.com/blockscout/blockscout/pull/1814) - Clear build artifacts script
- [#1837](https://github.com/blockscout/blockscout/pull/1837) - Add -f flag to clear_build.sh script delete static folder - [#1837](https://github.com/blockscout/blockscout/pull/1837) - Add -f flag to clear_build.sh script delete static folder
## 1.3.10-beta ## 1.3.10-beta

@ -159,6 +159,7 @@ test('prepare contract args | type: bool', () => {
} }
] ]
// cspell:ignore fals
document.getElementById('first').value = ' fals e ' document.getElementById('first').value = ' fals e '
const expectedValue = [false] const expectedValue = [false]
const $functionInputs = $('[data-function-form]').find('input[name=function_input]') const $functionInputs = $('[data-function-form]').find('input[name=function_input]')

@ -502,7 +502,7 @@ $dark-stakes-banned-background: #3e314c;
color: #fff; color: #fff;
} }
// info allert // info alert
.alert-info { .alert-info {
color: $labels-dark; color: $labels-dark;
background-color: $dark-light; background-color: $dark-light;

@ -303,7 +303,7 @@ export const elements = {
* values passed here will overwrite the values on asyncInitialState. * values passed here will overwrite the values on asyncInitialState.
* *
* itemKey: it will be added to the state as the key for diffing the elements and * itemKey: it will be added to the state as the key for diffing the elements and
* adding or removing with the correct animation. Check list_morph.js for more informantion. * adding or removing with the correct animation. Check list_morph.js for more information.
*/ */
export function createAsyncLoadStore (reducer, initialState, itemKey) { export function createAsyncLoadStore (reducer, initialState, itemKey) {
const state = merge(asyncInitialState, initialState) const state = merge(asyncInitialState, initialState)

@ -18,7 +18,7 @@ http://creativecommons.org/publicdomain/zero/1.0/legalcode
*/ */
export default function Queue(){ export default function Queue(){
// initialise the queue and offset // initialize the queue and offset
var queue = []; var queue = [];
var offset = 0; var offset = 0;

@ -224,7 +224,7 @@ export const elements = {
* values passed here will overwrite the values on asyncInitialState. * values passed here will overwrite the values on asyncInitialState.
* *
* itemKey: it will be added to the state as the key for diffing the elements and * itemKey: it will be added to the state as the key for diffing the elements and
* adding or removing with the correct animation. Check list_morph.js for more informantion. * adding or removing with the correct animation. Check list_morph.js for more information.
*/ */
export function createAsyncLoadStore (reducer, initialState, itemKey) { export function createAsyncLoadStore (reducer, initialState, itemKey) {
const state = merge(asyncInitialState, initialState) const state = merge(asyncInitialState, initialState)

@ -38,7 +38,7 @@ export function prepareMethodArgs ($functionInputs, inputs) {
} else { } else {
if (isArrayOfTuple(inputType)) { if (isArrayOfTuple(inputType)) {
const sanitizedInputValueElements = JSON.parse(sanitizedInputValue).map((elementValue, index) => { const sanitizedInputValueElements = JSON.parse(sanitizedInputValue).map((elementValue, index) => {
return sanitizeMutipleInputValues(elementValue, inputType, inputComponents) return sanitizeMultipleInputValues(elementValue, inputType, inputComponents)
}) })
return [sanitizedInputValueElements] return [sanitizedInputValueElements]
} else { } else {
@ -46,7 +46,7 @@ export function prepareMethodArgs ($functionInputs, inputs) {
sanitizedInputValue = sanitizedInputValue.substring(1, sanitizedInputValue.length - 1) sanitizedInputValue = sanitizedInputValue.substring(1, sanitizedInputValue.length - 1)
} }
const inputValueElements = sanitizedInputValue.split(',') const inputValueElements = sanitizedInputValue.split(',')
const sanitizedInputValueElements = sanitizeMutipleInputValues(inputValueElements, inputType, inputComponents) const sanitizedInputValueElements = sanitizeMultipleInputValues(inputValueElements, inputType, inputComponents)
return [sanitizedInputValueElements] return [sanitizedInputValueElements]
} }
} }
@ -54,7 +54,7 @@ export function prepareMethodArgs ($functionInputs, inputs) {
}) })
} }
function sanitizeMutipleInputValues (inputValueElements, inputType, inputComponents) { function sanitizeMultipleInputValues (inputValueElements, inputType, inputComponents) {
return inputValueElements.map((elementValue, index) => { return inputValueElements.map((elementValue, index) => {
let elementInputType let elementInputType
if (inputType.includes('tuple')) { if (inputType.includes('tuple')) {

@ -104,7 +104,7 @@ export async function disconnect () {
// If the cached provider is not cleared, // If the cached provider is not cleared,
// WalletConnect will default to the existing session // WalletConnect will default to the existing session
// and does not allow to re-scan the QR code with a new wallet. // and does not allow to re-scan the QR code with a new wallet.
// Depending on your use case you may want or want not his behavir. // Depending on your use case you may want or want not his behavior.
await web3Modal.clearCachedProvider() await web3Modal.clearCachedProvider()
} }

@ -258,9 +258,9 @@ defmodule BlockScoutWeb.Chain do
def param_to_block_timestamp(timestamp_string) when is_binary(timestamp_string) do def param_to_block_timestamp(timestamp_string) when is_binary(timestamp_string) do
case Integer.parse(timestamp_string) do case Integer.parse(timestamp_string) do
{temstamp_int, ""} -> {timestamp_int, ""} ->
timestamp = timestamp =
temstamp_int timestamp_int
|> DateTime.from_unix!(:second) |> DateTime.from_unix!(:second)
{:ok, timestamp} {:ok, timestamp}

@ -496,7 +496,7 @@ defmodule BlockScoutWeb.API.RPC.ContractController do
|> required_param(params, "contractaddress", "address_hash") |> required_param(params, "contractaddress", "address_hash")
|> required_param(params, "contractname", "name") |> required_param(params, "contractname", "name")
|> required_param(params, "compilerversion", "compiler_version") |> required_param(params, "compilerversion", "compiler_version")
|> optional_param(params, "constructorArguements", "constructor_arguments") |> optional_param(params, "constructorArguments", "constructor_arguments")
|> optional_param(params, "constructorArguments", "constructor_arguments") |> optional_param(params, "constructorArguments", "constructor_arguments")
end end

@ -46,7 +46,7 @@ defmodule BlockScoutWeb.API.V2.MainPageController do
finished_indexing_blocks: finished_indexing_blocks, finished_indexing_blocks: finished_indexing_blocks,
finished_indexing: Chain.finished_indexing?(indexed_ratio_blocks), finished_indexing: Chain.finished_indexing?(indexed_ratio_blocks),
indexed_blocks_ratio: indexed_ratio_blocks, indexed_blocks_ratio: indexed_ratio_blocks,
indexed_inernal_transactions_ratio: if(finished_indexing_blocks, do: Chain.indexed_ratio_internal_transactions()) indexed_internal_transactions_ratio: if(finished_indexing_blocks, do: Chain.indexed_ratio_internal_transactions())
}) })
end end
end end

@ -29,7 +29,7 @@ defmodule BlockScoutWeb.API.V2.TransactionController do
[to_address: :smart_contract] => :optional [to_address: :smart_contract] => :optional
} }
@token_transfers_neccessity_by_association %{ @token_transfers_necessity_by_association %{
[from_address: :smart_contract] => :optional, [from_address: :smart_contract] => :optional,
[to_address: :smart_contract] => :optional, [to_address: :smart_contract] => :optional,
[from_address: :names] => :optional, [from_address: :names] => :optional,
@ -38,7 +38,7 @@ defmodule BlockScoutWeb.API.V2.TransactionController do
to_address: :required to_address: :required
} }
@token_transfers_in_tx_neccessity_by_association %{ @token_transfers_in_tx_necessity_by_association %{
[from_address: :smart_contract] => :optional, [from_address: :smart_contract] => :optional,
[to_address: :smart_contract] => :optional, [to_address: :smart_contract] => :optional,
[from_address: :names] => :optional, [from_address: :names] => :optional,
@ -48,7 +48,7 @@ defmodule BlockScoutWeb.API.V2.TransactionController do
token: :required token: :required
} }
@internal_transaction_neccessity_by_association [ @internal_transaction_necessity_by_association [
necessity_by_association: %{ necessity_by_association: %{
[created_contract_address: :names] => :optional, [created_contract_address: :names] => :optional,
[from_address: :names] => :optional, [from_address: :names] => :optional,
@ -71,7 +71,7 @@ defmodule BlockScoutWeb.API.V2.TransactionController do
{:ok, false} <- AccessHelpers.restricted_access?(to_string(transaction.from_address_hash), params), {:ok, false} <- AccessHelpers.restricted_access?(to_string(transaction.from_address_hash), params),
{:ok, false} <- AccessHelpers.restricted_access?(to_string(transaction.to_address_hash), params), {:ok, false} <- AccessHelpers.restricted_access?(to_string(transaction.to_address_hash), params),
preloaded <- preloaded <-
Chain.preload_token_transfers(transaction, @token_transfers_in_tx_neccessity_by_association, false) do Chain.preload_token_transfers(transaction, @token_transfers_in_tx_necessity_by_association, false) do
conn conn
|> put_status(200) |> put_status(200)
|> render(:transaction, %{transaction: preloaded}) |> render(:transaction, %{transaction: preloaded})
@ -136,7 +136,7 @@ defmodule BlockScoutWeb.API.V2.TransactionController do
{:ok, false} <- AccessHelpers.restricted_access?(to_string(transaction.from_address_hash), params), {:ok, false} <- AccessHelpers.restricted_access?(to_string(transaction.from_address_hash), params),
{:ok, false} <- AccessHelpers.restricted_access?(to_string(transaction.to_address_hash), params) do {:ok, false} <- AccessHelpers.restricted_access?(to_string(transaction.to_address_hash), params) do
full_options = full_options =
[necessity_by_association: @token_transfers_neccessity_by_association] [necessity_by_association: @token_transfers_necessity_by_association]
|> Keyword.merge(paging_options(params)) |> Keyword.merge(paging_options(params))
|> Keyword.merge(token_transfers_types_options(params)) |> Keyword.merge(token_transfers_types_options(params))
@ -163,7 +163,7 @@ defmodule BlockScoutWeb.API.V2.TransactionController do
{:ok, false} <- AccessHelpers.restricted_access?(to_string(transaction.to_address_hash), params) do {:ok, false} <- AccessHelpers.restricted_access?(to_string(transaction.to_address_hash), params) do
full_options = full_options =
Keyword.merge( Keyword.merge(
@internal_transaction_neccessity_by_association, @internal_transaction_necessity_by_association,
paging_options(params) paging_options(params)
) )

@ -1240,7 +1240,7 @@ defmodule BlockScoutWeb.Etherscan do
latest will be the latest balance in a *consensus* block. latest will be the latest balance in a *consensus* block.
earliest will be the first recorded balance for the address. earliest will be the first recorded balance for the address.
pending will be the latest balance in consensus *or* nonconcensus blocks. pending will be the latest balance in consensus *or* nonconsensus blocks.
""" """
} }
], ],
@ -1496,7 +1496,7 @@ defmodule BlockScoutWeb.Etherscan do
placeholder: "transactionHash", placeholder: "transactionHash",
type: "string", type: "string",
description: description:
"Transaction hash. Hash of contents of the transaction. A transcation hash or address hash is required." "Transaction hash. Hash of contents of the transaction. A transaction hash or address hash is required."
} }
], ],
optional_params: [ optional_params: [
@ -2190,7 +2190,7 @@ defmodule BlockScoutWeb.Etherscan do
@block_eth_block_number_action %{ @block_eth_block_number_action %{
name: "eth_block_number", name: "eth_block_number",
description: "Mimics Ethereum JSON RPC's eth_blockNumber. Returns the lastest block number", description: "Mimics Ethereum JSON RPC's eth_blockNumber. Returns the latest block number",
required_params: [], required_params: [],
optional_params: [ optional_params: [
%{ %{
@ -2689,7 +2689,7 @@ defmodule BlockScoutWeb.Etherscan do
], ],
optional_params: [ optional_params: [
%{ %{
key: "constructorArguements", key: "constructorArguments",
type: "string", type: "string",
description: "The constructor argument data provided." description: "The constructor argument data provided."
}, },

@ -1,6 +1,6 @@
defmodule BlockScoutWeb.PagingHelper do defmodule BlockScoutWeb.PagingHelper do
@moduledoc """ @moduledoc """
Helper for fetching filters and other url query paramters Helper for fetching filters and other url query parameters
""" """
import Explorer.Chain, only: [string_to_transaction_hash: 1] import Explorer.Chain, only: [string_to_transaction_hash: 1]
alias Explorer.PagingOptions alias Explorer.PagingOptions

@ -1,7 +1,7 @@
# This file in ignore list of `sobelow`, be careful while adding new endpoints here # This file in ignore list of `sobelow`, be careful while adding new endpoints here
defmodule BlockScoutWeb.SmartContractsApiV2Router do defmodule BlockScoutWeb.SmartContractsApiV2Router do
@moduledoc """ @moduledoc """
Router for /api/v2/smart-contracts. This route has separate router in order to ignore solelow's warning about missing CSRF protection Router for /api/v2/smart-contracts. This route has separate router in order to ignore sobelow's warning about missing CSRF protection
""" """
use BlockScoutWeb, :router use BlockScoutWeb, :router
alias BlockScoutWeb.Plug.CheckApiV2 alias BlockScoutWeb.Plug.CheckApiV2

@ -16,6 +16,6 @@
</div> </div>
<%= error_tag @f, :is_yul, id: "is_yul-help-block", class: "text-danger form-error" %> <%= error_tag @f, :is_yul, id: "is_yul-help-block", class: "text-danger form-error" %>
</div> </div>
<div class="smart-contract-form-group-tooltip"><%= gettext("Select Yes if you want to vefify Yul contract.") %></div> <div class="smart-contract-form-group-tooltip"><%= gettext("Select Yes if you want to verify Yul contract.") %></div>
</div> </div>
</div> </div>

@ -1,7 +1,7 @@
<div data-test="address_log" class="tile tile-muted" data-identifier-log="<%= "#{to_string(@log.transaction.hash)}#{@log.index}" %>"> <div data-test="address_log" class="tile tile-muted" data-identifier-log="<%= "#{to_string(@log.transaction.hash)}#{@log.index}" %>">
<% decoded_result = decode(@log, @log.transaction) %> <% decoded_result = decode(@log, @log.transaction) %>
<%= case decoded_result do %> <%= case decoded_result do %>
<% {:error, :contract_not_verified, _cadidates} -> %> <% {:error, :contract_not_verified, _candidates} -> %>
<div class="alert alert-info"> <div class="alert alert-info">
<%= gettext "To see accurate decoded input data, the contract must be verified." %> <%= gettext "To see accurate decoded input data, the contract must be verified." %>
<%= case @log.transaction do %> <%= case @log.transaction do %>

@ -1,7 +1,7 @@
<div data-test="transaction_log" class="tile tile-muted"> <div data-test="transaction_log" class="tile tile-muted">
<% decoded_result = decode(@log, @transaction) %> <% decoded_result = decode(@log, @transaction) %>
<%= case decoded_result do %> <%= case decoded_result do %>
<% {:error, :contract_not_verified, _cadidates} -> %> <% {:error, :contract_not_verified, _candidates} -> %>
<div class="alert alert-info"> <div class="alert alert-info">
<%= gettext "To see accurate decoded input data, the contract must be verified." %> <%= gettext "To see accurate decoded input data, the contract must be verified." %>
<%= case @log do %> <%= case @log do %>

@ -41,7 +41,7 @@
<i style="color: #dc3545;" class="fa-regular fa-circle-xmark"></i> <i style="color: #dc3545;" class="fa-regular fa-circle-xmark"></i>
<% end %> <% end %>
</td> </td>
<!-- Construcor agruments --> <!-- Constructor arguments -->
<td class="stakes-td text-center"> <td class="stakes-td text-center">
<%= if @contract.constructor_arguments do %> <%= if @contract.constructor_arguments do %>
<i style="color: #20b760;" class="fa-regular fa-circle-check"></i> <i style="color: #20b760;" class="fa-regular fa-circle-check"></i>

@ -4,5 +4,5 @@
subnetwork: BlockScoutWeb.LayoutView.subnetwork_title() subnetwork: BlockScoutWeb.LayoutView.subnetwork_title()
) %> ) %>
</title> </title>
<meta name="keywords" content="<%= gettext "Verifed contracts, %{subnetwork}, %{coin}", subnetwork: BlockScoutWeb.LayoutView.subnetwork_title(), coin: Explorer.coin() %>"> <meta name="keywords" content="<%= gettext "Verified contracts, %{subnetwork}, %{coin}", subnetwork: BlockScoutWeb.LayoutView.subnetwork_title(), coin: Explorer.coin() %>">
<meta name="description" content="<%= gettext "View the verified contracts on %{subnetwork}", subnetwork: BlockScoutWeb.LayoutView.subnetwork_title() %>"> <meta name="description" content="<%= gettext "View the verified contracts on %{subnetwork}", subnetwork: BlockScoutWeb.LayoutView.subnetwork_title() %>">

@ -168,7 +168,7 @@ defmodule BlockScoutWeb.API.V2.SmartContractView do
"abi" => target_contract.abi, "abi" => target_contract.abi,
"source_code" => target_contract.contract_source_code, "source_code" => target_contract.contract_source_code,
"file_path" => target_contract.file_path, "file_path" => target_contract.file_path,
"additional_sources" => Enum.map(additional_sources, &prepare_additional_sourse/1), "additional_sources" => Enum.map(additional_sources, &prepare_additional_source/1),
"compiler_settings" => target_contract.compiler_settings, "compiler_settings" => target_contract.compiler_settings,
"external_libraries" => prepare_external_libraries(target_contract.external_libraries), "external_libraries" => prepare_external_libraries(target_contract.external_libraries),
"constructor_args" => if(smart_contract_verified, do: target_contract.constructor_arguments), "constructor_args" => if(smart_contract_verified, do: target_contract.constructor_arguments),
@ -210,7 +210,7 @@ defmodule BlockScoutWeb.API.V2.SmartContractView do
end) end)
end end
defp prepare_additional_sourse(source) do defp prepare_additional_source(source) do
%{ %{
"source_code" => source.contract_source_code, "source_code" => source.contract_source_code,
"file_path" => source.file_name "file_path" => source.file_name

@ -19,13 +19,13 @@ defmodule BlockScoutWeb.FormView do
* `:label` - Label for the input field * `:label` - Label for the input field
## Options as HTML 5 Attriutes ## Options as HTML 5 Attributes
The following options will be applied as HTML 5 attributes on the The following options will be applied as HTML 5 attributes on the
`<input>` element: `<input>` element:
* `:default_value` - Default value to attach to the input field * `:default_value` - Default value to attach to the input field
* `:id` - ID to attatch to the input field * `:id` - ID to attach to the input field
* `:placeholder` - Placeholder text for the input field * `:placeholder` - Placeholder text for the input field
* `:required` - Mark the input field as required * `:required` - Mark the input field as required
* `:type` - Input field type * `:type` - Input field type

@ -590,19 +590,19 @@ defmodule BlockScoutWeb.TransactionView do
case revert_reason do case revert_reason do
"0x" <> hex_part -> "0x" <> hex_part ->
proccess_hex_revert_reason(hex_part) process_hex_revert_reason(hex_part)
hex_part -> hex_part ->
proccess_hex_revert_reason(hex_part) process_hex_revert_reason(hex_part)
end end
end end
# Function converts hex revert reason to the binary # Function converts hex revert reason to the binary
@spec proccess_hex_revert_reason(nil) :: nil @spec process_hex_revert_reason(nil) :: nil
defp proccess_hex_revert_reason(nil), do: nil defp process_hex_revert_reason(nil), do: nil
@spec proccess_hex_revert_reason(binary()) :: binary() @spec process_hex_revert_reason(binary()) :: binary()
defp proccess_hex_revert_reason(hex_revert_reason) do defp process_hex_revert_reason(hex_revert_reason) do
case Integer.parse(hex_revert_reason, 16) do case Integer.parse(hex_revert_reason, 16) do
{number, ""} -> {number, ""} ->
:binary.encode_unsigned(number) :binary.encode_unsigned(number)

@ -2218,11 +2218,6 @@ msgstr ""
msgid "Search tokens" msgid "Search tokens"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/address_contract_verification_common_fields/_yul_contracts_switcher.html.eex:19
#, elixir-autogen, elixir-format
msgid "Select Yes if you want to vefify Yul contract."
msgstr ""
#: lib/block_scout_web/templates/address_contract_verification_common_fields/_include_nightly_builds_field.html.eex:19 #: lib/block_scout_web/templates/address_contract_verification_common_fields/_include_nightly_builds_field.html.eex:19
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Select yes if you want to show nightly builds." msgid "Select yes if you want to show nightly builds."
@ -3074,11 +3069,6 @@ msgstr ""
msgid "Value sent in the native token (and USD) if applicable." msgid "Value sent in the native token (and USD) if applicable."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/verified_contracts/_metatags.html.eex:7
#, elixir-autogen, elixir-format
msgid "Verifed contracts, %{subnetwork}, %{coin}"
msgstr ""
#: lib/block_scout_web/templates/address_read_contract/index.html.eex:17 #: lib/block_scout_web/templates/address_read_contract/index.html.eex:17
#: lib/block_scout_web/templates/address_write_contract/index.html.eex:15 #: lib/block_scout_web/templates/address_write_contract/index.html.eex:15
#: lib/block_scout_web/templates/verified_contracts/index.html.eex:75 #: lib/block_scout_web/templates/verified_contracts/index.html.eex:75
@ -3539,3 +3529,13 @@ msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Potential matches from contract method database:" msgid "Potential matches from contract method database:"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/address_contract_verification_common_fields/_yul_contracts_switcher.html.eex:19
#, elixir-autogen, elixir-format
msgid "Select Yes if you want to verify Yul contract."
msgstr ""
#: lib/block_scout_web/templates/verified_contracts/_metatags.html.eex:7
#, elixir-autogen, elixir-format
msgid "Verified contracts, %{subnetwork}, %{coin}"
msgstr ""

@ -2218,11 +2218,6 @@ msgstr ""
msgid "Search tokens" msgid "Search tokens"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/address_contract_verification_common_fields/_yul_contracts_switcher.html.eex:19
#, elixir-autogen, elixir-format
msgid "Select Yes if you want to vefify Yul contract."
msgstr ""
#: lib/block_scout_web/templates/address_contract_verification_common_fields/_include_nightly_builds_field.html.eex:19 #: lib/block_scout_web/templates/address_contract_verification_common_fields/_include_nightly_builds_field.html.eex:19
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Select yes if you want to show nightly builds." msgid "Select yes if you want to show nightly builds."
@ -3074,11 +3069,6 @@ msgstr ""
msgid "Value sent in the native token (and USD) if applicable." msgid "Value sent in the native token (and USD) if applicable."
msgstr "" msgstr ""
#: lib/block_scout_web/templates/verified_contracts/_metatags.html.eex:7
#, elixir-autogen, elixir-format
msgid "Verifed contracts, %{subnetwork}, %{coin}"
msgstr ""
#: lib/block_scout_web/templates/address_read_contract/index.html.eex:17 #: lib/block_scout_web/templates/address_read_contract/index.html.eex:17
#: lib/block_scout_web/templates/address_write_contract/index.html.eex:15 #: lib/block_scout_web/templates/address_write_contract/index.html.eex:15
#: lib/block_scout_web/templates/verified_contracts/index.html.eex:75 #: lib/block_scout_web/templates/verified_contracts/index.html.eex:75
@ -3539,3 +3529,13 @@ msgstr ""
#, elixir-autogen, elixir-format, fuzzy #, elixir-autogen, elixir-format, fuzzy
msgid "Potential matches from contract method database:" msgid "Potential matches from contract method database:"
msgstr "" msgstr ""
#: lib/block_scout_web/templates/address_contract_verification_common_fields/_yul_contracts_switcher.html.eex:19
#, elixir-autogen, elixir-format, fuzzy
msgid "Select Yes if you want to verify Yul contract."
msgstr ""
#: lib/block_scout_web/templates/verified_contracts/_metatags.html.eex:7
#, elixir-autogen, elixir-format, fuzzy
msgid "Verified contracts, %{subnetwork}, %{coin}"
msgstr ""

@ -72,7 +72,7 @@ defmodule BlockScoutWeb.ChainTest do
end end
end end
describe "Posion.encode!" do describe "Poison.encode!" do
test "correctly encodes decimal values" do test "correctly encodes decimal values" do
val = Decimal.from_float(5.55) val = Decimal.from_float(5.55)

@ -779,10 +779,10 @@ defmodule BlockScoutWeb.Account.Api.V1.UserControllerTest do
end end
describe "public tags" do describe "public tags" do
test "create public tags reuqest", %{conn: conn} do test "create public tags request", %{conn: conn} do
public_tags_request = build(:public_tags_request) public_tags_request = build(:public_tags_request)
post_public_tasg_request_response = post_public_tags_request_response =
conn conn
|> post( |> post(
"/api/account/v1/user/public_tags", "/api/account/v1/user/public_tags",
@ -791,21 +791,21 @@ defmodule BlockScoutWeb.Account.Api.V1.UserControllerTest do
|> doc(description: "Submit request to add a public tag") |> doc(description: "Submit request to add a public tag")
|> json_response(200) |> json_response(200)
assert post_public_tasg_request_response["full_name"] == public_tags_request["full_name"] assert post_public_tags_request_response["full_name"] == public_tags_request["full_name"]
assert post_public_tasg_request_response["email"] == public_tags_request["email"] assert post_public_tags_request_response["email"] == public_tags_request["email"]
assert post_public_tasg_request_response["tags"] == public_tags_request["tags"] assert post_public_tags_request_response["tags"] == public_tags_request["tags"]
assert post_public_tasg_request_response["website"] == public_tags_request["website"] assert post_public_tags_request_response["website"] == public_tags_request["website"]
assert post_public_tasg_request_response["additional_comment"] == public_tags_request["additional_comment"] assert post_public_tags_request_response["additional_comment"] == public_tags_request["additional_comment"]
assert post_public_tasg_request_response["addresses"] == public_tags_request["addresses"] assert post_public_tags_request_response["addresses"] == public_tags_request["addresses"]
assert post_public_tasg_request_response["company"] == public_tags_request["company"] assert post_public_tags_request_response["company"] == public_tags_request["company"]
assert post_public_tasg_request_response["is_owner"] == public_tags_request["is_owner"] assert post_public_tags_request_response["is_owner"] == public_tags_request["is_owner"]
assert post_public_tasg_request_response["id"] assert post_public_tags_request_response["id"]
end end
test "get one public tags requests", %{conn: conn} do test "get one public tags requests", %{conn: conn} do
public_tags_request = build(:public_tags_request) public_tags_request = build(:public_tags_request)
post_public_tasg_request_response = post_public_tags_request_response =
conn conn
|> post( |> post(
"/api/account/v1/user/public_tags", "/api/account/v1/user/public_tags",
@ -813,21 +813,21 @@ defmodule BlockScoutWeb.Account.Api.V1.UserControllerTest do
) )
|> json_response(200) |> json_response(200)
assert post_public_tasg_request_response["full_name"] == public_tags_request["full_name"] assert post_public_tags_request_response["full_name"] == public_tags_request["full_name"]
assert post_public_tasg_request_response["email"] == public_tags_request["email"] assert post_public_tags_request_response["email"] == public_tags_request["email"]
assert post_public_tasg_request_response["tags"] == public_tags_request["tags"] assert post_public_tags_request_response["tags"] == public_tags_request["tags"]
assert post_public_tasg_request_response["website"] == public_tags_request["website"] assert post_public_tags_request_response["website"] == public_tags_request["website"]
assert post_public_tasg_request_response["additional_comment"] == public_tags_request["additional_comment"] assert post_public_tags_request_response["additional_comment"] == public_tags_request["additional_comment"]
assert post_public_tasg_request_response["addresses"] == public_tags_request["addresses"] assert post_public_tags_request_response["addresses"] == public_tags_request["addresses"]
assert post_public_tasg_request_response["company"] == public_tags_request["company"] assert post_public_tags_request_response["company"] == public_tags_request["company"]
assert post_public_tasg_request_response["is_owner"] == public_tags_request["is_owner"] assert post_public_tags_request_response["is_owner"] == public_tags_request["is_owner"]
assert post_public_tasg_request_response["id"] assert post_public_tags_request_response["id"]
assert conn assert conn
|> get("/api/account/v1/user/public_tags") |> get("/api/account/v1/user/public_tags")
|> json_response(200) |> json_response(200)
|> Enum.map(&convert_date/1) == |> Enum.map(&convert_date/1) ==
[post_public_tasg_request_response] [post_public_tags_request_response]
|> Enum.map(&convert_date/1) |> Enum.map(&convert_date/1)
end end
@ -886,7 +886,7 @@ defmodule BlockScoutWeb.Account.Api.V1.UserControllerTest do
test "edit public tags request", %{conn: conn} do test "edit public tags request", %{conn: conn} do
public_tags_request = build(:public_tags_request) public_tags_request = build(:public_tags_request)
post_public_tasg_request_response = post_public_tags_request_response =
conn conn
|> post( |> post(
"/api/account/v1/user/public_tags", "/api/account/v1/user/public_tags",
@ -894,49 +894,49 @@ defmodule BlockScoutWeb.Account.Api.V1.UserControllerTest do
) )
|> json_response(200) |> json_response(200)
assert post_public_tasg_request_response["full_name"] == public_tags_request["full_name"] assert post_public_tags_request_response["full_name"] == public_tags_request["full_name"]
assert post_public_tasg_request_response["email"] == public_tags_request["email"] assert post_public_tags_request_response["email"] == public_tags_request["email"]
assert post_public_tasg_request_response["tags"] == public_tags_request["tags"] assert post_public_tags_request_response["tags"] == public_tags_request["tags"]
assert post_public_tasg_request_response["website"] == public_tags_request["website"] assert post_public_tags_request_response["website"] == public_tags_request["website"]
assert post_public_tasg_request_response["additional_comment"] == public_tags_request["additional_comment"] assert post_public_tags_request_response["additional_comment"] == public_tags_request["additional_comment"]
assert post_public_tasg_request_response["addresses"] == public_tags_request["addresses"] assert post_public_tags_request_response["addresses"] == public_tags_request["addresses"]
assert post_public_tasg_request_response["company"] == public_tags_request["company"] assert post_public_tags_request_response["company"] == public_tags_request["company"]
assert post_public_tasg_request_response["is_owner"] == public_tags_request["is_owner"] assert post_public_tags_request_response["is_owner"] == public_tags_request["is_owner"]
assert post_public_tasg_request_response["id"] assert post_public_tags_request_response["id"]
assert conn assert conn
|> get("/api/account/v1/user/public_tags") |> get("/api/account/v1/user/public_tags")
|> json_response(200) |> json_response(200)
|> Enum.map(&convert_date/1) == |> Enum.map(&convert_date/1) ==
[post_public_tasg_request_response] [post_public_tags_request_response]
|> Enum.map(&convert_date/1) |> Enum.map(&convert_date/1)
new_public_tags_request = build(:public_tags_request) new_public_tags_request = build(:public_tags_request)
put_public_tasg_request_response = put_public_tags_request_response =
conn conn
|> put( |> put(
"/api/account/v1/user/public_tags/#{post_public_tasg_request_response["id"]}", "/api/account/v1/user/public_tags/#{post_public_tags_request_response["id"]}",
new_public_tags_request new_public_tags_request
) )
|> doc(description: "Edit request to add a public tag") |> doc(description: "Edit request to add a public tag")
|> json_response(200) |> json_response(200)
assert put_public_tasg_request_response["full_name"] == new_public_tags_request["full_name"] assert put_public_tags_request_response["full_name"] == new_public_tags_request["full_name"]
assert put_public_tasg_request_response["email"] == new_public_tags_request["email"] assert put_public_tags_request_response["email"] == new_public_tags_request["email"]
assert put_public_tasg_request_response["tags"] == new_public_tags_request["tags"] assert put_public_tags_request_response["tags"] == new_public_tags_request["tags"]
assert put_public_tasg_request_response["website"] == new_public_tags_request["website"] assert put_public_tags_request_response["website"] == new_public_tags_request["website"]
assert put_public_tasg_request_response["additional_comment"] == new_public_tags_request["additional_comment"] assert put_public_tags_request_response["additional_comment"] == new_public_tags_request["additional_comment"]
assert put_public_tasg_request_response["addresses"] == new_public_tags_request["addresses"] assert put_public_tags_request_response["addresses"] == new_public_tags_request["addresses"]
assert put_public_tasg_request_response["company"] == new_public_tags_request["company"] assert put_public_tags_request_response["company"] == new_public_tags_request["company"]
assert put_public_tasg_request_response["is_owner"] == new_public_tags_request["is_owner"] assert put_public_tags_request_response["is_owner"] == new_public_tags_request["is_owner"]
assert put_public_tasg_request_response["id"] == post_public_tasg_request_response["id"] assert put_public_tags_request_response["id"] == post_public_tags_request_response["id"]
assert conn assert conn
|> get("/api/account/v1/user/public_tags") |> get("/api/account/v1/user/public_tags")
|> json_response(200) |> json_response(200)
|> Enum.map(&convert_date/1) == |> Enum.map(&convert_date/1) ==
[put_public_tasg_request_response] [put_public_tags_request_response]
|> Enum.map(&convert_date/1) |> Enum.map(&convert_date/1)
end end
end end

@ -108,7 +108,7 @@ defmodule BlockScoutWeb.API.V1.DecompiledControllerTest do
end end
describe "when user is not authorized" do describe "when user is not authorized" do
test "returns forbedden", %{conn: conn} do test "returns forbidden", %{conn: conn} do
request = post(conn, api_v1_decompiled_smart_contract_path(conn, :create)) request = post(conn, api_v1_decompiled_smart_contract_path(conn, :create))
assert request.status == 403 assert request.status == 403

@ -34,7 +34,7 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
test "get address & get the same response for checksummed and downcased parameter", %{conn: conn} do test "get address & get the same response for checksummed and downcased parameter", %{conn: conn} do
address = insert(:address) address = insert(:address)
correct_reponse = %{ correct_response = %{
"hash" => Address.checksum(address.hash), "hash" => Address.checksum(address.hash),
"is_contract" => false, "is_contract" => false,
"is_verified" => false, "is_verified" => false,
@ -64,10 +64,10 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
} }
request = get(conn, "/api/v2/addresses/#{Address.checksum(address.hash)}") request = get(conn, "/api/v2/addresses/#{Address.checksum(address.hash)}")
assert ^correct_reponse = json_response(request, 200) assert ^correct_response = json_response(request, 200)
request = get(conn, "/api/v2/addresses/#{String.downcase(to_string(address.hash))}") request = get(conn, "/api/v2/addresses/#{String.downcase(to_string(address.hash))}")
assert ^correct_reponse = json_response(request, 200) assert ^correct_response = json_response(request, 200)
end end
end end
@ -389,7 +389,7 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
compare_item(token_transfer, Enum.at(response["items"], 0)) compare_item(token_transfer, Enum.at(response["items"], 0))
end end
test "method in token transer could be decoded", %{conn: conn} do test "method in token transfer could be decoded", %{conn: conn} do
insert(:contract_method, insert(:contract_method,
identifier: Base.decode16!("731133e9", case: :lower), identifier: Base.decode16!("731133e9", case: :lower),
abi: %{ abi: %{
@ -467,7 +467,7 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
token = insert(:token) token = insert(:token)
token_tranfers = token_transfers =
for _ <- 0..50 do for _ <- 0..50 do
tx = insert(:transaction, input: "0xabcd010203040506") |> with_block() tx = insert(:transaction, input: "0xabcd010203040506") |> with_block()
@ -491,7 +491,7 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
assert response_2nd_page = json_response(request_2nd_page, 200) assert response_2nd_page = json_response(request_2nd_page, 200)
check_paginated_response(response, response_2nd_page, token_tranfers) check_paginated_response(response, response_2nd_page, token_transfers)
end end
test "get only :to token transfer", %{conn: conn} do test "get only :to token transfer", %{conn: conn} do
@ -532,7 +532,7 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
test "token transfers can paginate", %{conn: conn} do test "token transfers can paginate", %{conn: conn} do
address = insert(:address) address = insert(:address)
token_tranfers = token_transfers =
for _ <- 0..50 do for _ <- 0..50 do
tx = insert(:transaction, input: "0xabcd010203040506") |> with_block() tx = insert(:transaction, input: "0xabcd010203040506") |> with_block()
@ -545,7 +545,7 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
request_2nd_page = get(conn, "/api/v2/addresses/#{address.hash}/token-transfers", response["next_page_params"]) request_2nd_page = get(conn, "/api/v2/addresses/#{address.hash}/token-transfers", response["next_page_params"])
assert response_2nd_page = json_response(request_2nd_page, 200) assert response_2nd_page = json_response(request_2nd_page, 200)
check_paginated_response(response, response_2nd_page, token_tranfers) check_paginated_response(response, response_2nd_page, token_transfers)
end end
test ":to token transfers can paginate", %{conn: conn} do test ":to token transfers can paginate", %{conn: conn} do
@ -556,7 +556,7 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
insert(:token_transfer, transaction: tx, block: tx.block, block_number: tx.block_number, from_address: address) insert(:token_transfer, transaction: tx, block: tx.block, block_number: tx.block_number, from_address: address)
end end
token_tranfers = token_transfers =
for _ <- 0..50 do for _ <- 0..50 do
tx = insert(:transaction, input: "0xabcd010203040506") |> with_block() tx = insert(:transaction, input: "0xabcd010203040506") |> with_block()
insert(:token_transfer, transaction: tx, block: tx.block, block_number: tx.block_number, to_address: address) insert(:token_transfer, transaction: tx, block: tx.block, block_number: tx.block_number, to_address: address)
@ -571,13 +571,13 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
assert response_2nd_page = json_response(request_2nd_page, 200) assert response_2nd_page = json_response(request_2nd_page, 200)
check_paginated_response(response, response_2nd_page, token_tranfers) check_paginated_response(response, response_2nd_page, token_transfers)
end end
test ":from token transfers can paginate", %{conn: conn} do test ":from token transfers can paginate", %{conn: conn} do
address = insert(:address) address = insert(:address)
token_tranfers = token_transfers =
for _ <- 0..50 do for _ <- 0..50 do
tx = insert(:transaction, input: "0xabcd010203040506") |> with_block() tx = insert(:transaction, input: "0xabcd010203040506") |> with_block()
@ -598,7 +598,7 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
assert response_2nd_page = json_response(request_2nd_page, 200) assert response_2nd_page = json_response(request_2nd_page, 200)
check_paginated_response(response, response_2nd_page, token_tranfers) check_paginated_response(response, response_2nd_page, token_transfers)
end end
test ":from + :to tt can paginate", %{conn: conn} do test ":from + :to tt can paginate", %{conn: conn} do

@ -58,7 +58,7 @@ defmodule BlockScoutWeb.API.V2.MainPageControllerTest do
assert Map.has_key?(request, "finished_indexing_blocks") assert Map.has_key?(request, "finished_indexing_blocks")
assert Map.has_key?(request, "finished_indexing") assert Map.has_key?(request, "finished_indexing")
assert Map.has_key?(request, "indexed_blocks_ratio") assert Map.has_key?(request, "indexed_blocks_ratio")
assert Map.has_key?(request, "indexed_inernal_transactions_ratio") assert Map.has_key?(request, "indexed_internal_transactions_ratio")
end end
end end

@ -120,7 +120,7 @@ defmodule BlockScoutWeb.API.V2.TokenControllerTest do
test "check pagination", %{conn: conn} do test "check pagination", %{conn: conn} do
token = insert(:token) token = insert(:token)
token_tranfers = token_transfers =
for _ <- 0..50 do for _ <- 0..50 do
tx = insert(:transaction, input: "0xabcd010203040506") |> with_block() tx = insert(:transaction, input: "0xabcd010203040506") |> with_block()
@ -140,7 +140,7 @@ defmodule BlockScoutWeb.API.V2.TokenControllerTest do
assert response_2nd_page = json_response(request_2nd_page, 200) assert response_2nd_page = json_response(request_2nd_page, 200)
check_paginated_response(response, response_2nd_page, token_tranfers) check_paginated_response(response, response_2nd_page, token_transfers)
end end
end end
@ -408,7 +408,7 @@ defmodule BlockScoutWeb.API.V2.TokenControllerTest do
assert %{"message" => "Invalid parameter(s)"} = json_response(request, 422) assert %{"message" => "Invalid parameter(s)"} = json_response(request, 422)
end end
test "recieve 0 count", %{conn: conn} do test "receive 0 count", %{conn: conn} do
token = insert(:token) token = insert(:token)
insert(:token_instance, token_id: 0, token_contract_address_hash: token.contract_address_hash) insert(:token_instance, token_id: 0, token_contract_address_hash: token.contract_address_hash)

@ -13,7 +13,7 @@ defmodule BlockScoutWeb.AddressContractVerificationTest do
{:ok, bypass: bypass} {:ok, bypass: bypass}
end end
# wallaby with chrome headles always fails this test # wallaby with chrome headless always fails this test
@tag :skip @tag :skip
test "users validates smart contract", %{session: session, bypass: bypass} do test "users validates smart contract", %{session: session, bypass: bypass} do
Bypass.expect(bypass, fn conn -> Conn.resp(conn, 200, solc_bin_versions()) end) Bypass.expect(bypass, fn conn -> Conn.resp(conn, 200, solc_bin_versions()) end)

@ -83,7 +83,7 @@ defmodule BlockScoutWeb.ViewingTransactionsTest do
|> refute_has(TransactionListPage.transaction(pending)) |> refute_has(TransactionListPage.transaction(pending))
end end
test "viewing the pending tranasctions list", %{ test "viewing the pending transactions list", %{
pending: pending, pending: pending,
pending_contract: pending_contract, pending_contract: pending_contract,
session: session session: session

@ -419,7 +419,7 @@ defmodule BlockScoutWeb.Schema.Query.AddressTest do
end end
test "with 'last' and 'count' arguments", %{conn: conn} do test "with 'last' and 'count' arguments", %{conn: conn} do
# "`last: N` must always be acompanied by either a `before:` argument to # "`last: N` must always be accompanied by either a `before:` argument to
# the query, or an explicit `count:` option to the `from_query` call. # the query, or an explicit `count:` option to the `from_query` call.
# Otherwise it is impossible to derive the required offset." # Otherwise it is impossible to derive the required offset."
# https://hexdocs.pm/absinthe_relay/Absinthe.Relay.Connection.html#from_query/4 # https://hexdocs.pm/absinthe_relay/Absinthe.Relay.Connection.html#from_query/4

@ -159,7 +159,7 @@ defmodule BlockScoutWeb.Schema.Query.TokenTransfersTest do
end end
test "with 'last' and 'count' arguments", %{conn: conn} do test "with 'last' and 'count' arguments", %{conn: conn} do
# "`last: N` must always be acompanied by either a `before:` argument to # "`last: N` must always be accompanied by either a `before:` argument to
# the query, or an explicit `count:` option to the `from_query` call. # the query, or an explicit `count:` option to the `from_query` call.
# Otherwise it is impossible to derive the required offset." # Otherwise it is impossible to derive the required offset."
# https://hexdocs.pm/absinthe_relay/Absinthe.Relay.Connection.html#from_query/4 # https://hexdocs.pm/absinthe_relay/Absinthe.Relay.Connection.html#from_query/4

@ -382,7 +382,7 @@ defmodule BlockScoutWeb.Schema.Query.TransactionTest do
end end
test "with 'last' and 'count' arguments", %{conn: conn} do test "with 'last' and 'count' arguments", %{conn: conn} do
# "`last: N` must always be acompanied by either a `before:` argument to # "`last: N` must always be accompanied by either a `before:` argument to
# the query, or an explicit `count:` option to the `from_query` call. # the query, or an explicit `count:` option to the `from_query` call.
# Otherwise it is impossible to derive the required offset." # Otherwise it is impossible to derive the required offset."
# https://hexdocs.pm/absinthe_relay/Absinthe.Relay.Connection.html#from_query/4 # https://hexdocs.pm/absinthe_relay/Absinthe.Relay.Connection.html#from_query/4

@ -35,7 +35,7 @@ defmodule BlockScoutWeb.TransactionViewTest do
assert pending.inserted_at == TransactionView.block_timestamp(pending) assert pending.inserted_at == TransactionView.block_timestamp(pending)
end end
test "returns timestamp for block for collacted transaction" do test "returns timestamp for block for collated transaction" do
block = insert(:block) block = insert(:block)
transaction = transaction =

@ -83,7 +83,7 @@ defmodule EthereumJSONRPC do
* `:transport` - the `t:EthereumJSONRPC.Transport.t/0` callback module * `:transport` - the `t:EthereumJSONRPC.Transport.t/0` callback module
* `:transport_options` - options passed to `c:EthereumJSONRPC.Transport.json_rpc/2` * `:transport_options` - options passed to `c:EthereumJSONRPC.Transport.json_rpc/2`
* `:variant` - the `t:EthereumJSONRPC.Variant.t/0` callback module * `:variant` - the `t:EthereumJSONRPC.Variant.t/0` callback module
* `:throttle_timout` - the maximum amount of time in milliseconds to throttle * `:throttle_timeout` - the maximum amount of time in milliseconds to throttle
before automatically returning a timeout. Defaults to #{@default_throttle_timeout} milliseconds. before automatically returning a timeout. Defaults to #{@default_throttle_timeout} milliseconds.
""" """
@type json_rpc_named_arguments :: [ @type json_rpc_named_arguments :: [

@ -13,7 +13,7 @@ defmodule EthereumJSONRPC.Log do
* `"blockHash"` - `t:EthereumJSONRPC.hash/0` of the block this transaction is in. * `"blockHash"` - `t:EthereumJSONRPC.hash/0` of the block this transaction is in.
* `"blockNumber"` - `t:EthereumJSONRPC.quantity/0` for the block number this transaction is in. * `"blockNumber"` - `t:EthereumJSONRPC.quantity/0` for the block number this transaction is in.
* `"data"` - Data containing non-indexed log parameter * `"data"` - Data containing non-indexed log parameter
* `"logIndex"` - `t:EthereumJSONRPC.quantity/0` of the event index positon in the block. * `"logIndex"` - `t:EthereumJSONRPC.quantity/0` of the event index position in the block.
* `"topics"` - `t:list/0` of at most 4 32-byte topics. Topic 1-3 contains indexed parameters of the log. * `"topics"` - `t:list/0` of at most 4 32-byte topics. Topic 1-3 contains indexed parameters of the log.
* `"transactionHash"` - `t:EthereumJSONRPC.hash/0` of the transaction * `"transactionHash"` - `t:EthereumJSONRPC.hash/0` of the transaction
* `"transactionIndex"` - `t:EthereumJSONRPC.quantity/0` for the index of the transaction in the block. * `"transactionIndex"` - `t:EthereumJSONRPC.quantity/0` for the index of the transaction in the block.

@ -35,7 +35,7 @@ defmodule EthereumJSONRPC.PendingTransaction do
end end
@doc """ @doc """
Зфкшен-style fetching of pending transactions (from `parity_pendingTransactions`) parity-style fetching of pending transactions (from `parity_pendingTransactions`)
""" """
@spec fetch_pending_transactions_parity(EthereumJSONRPC.json_rpc_named_arguments()) :: @spec fetch_pending_transactions_parity(EthereumJSONRPC.json_rpc_named_arguments()) ::
{:ok, [Transaction.params()]} | {:error, reason :: term} {:ok, [Transaction.params()]} | {:error, reason :: term}

@ -16,11 +16,11 @@ defmodule EthereumJSONRPC.RequestCoordinator do
* `:table` - name of the ets table to store the data in * `:table` - name of the ets table to store the data in
* `:wait_per_timeout` - Milliseconds to wait for each recent timeout within * `:wait_per_timeout` - Milliseconds to wait for each recent timeout within
the tracked window the tracked window
* `:max_jitter` - Maximimum amount of time in milliseconds to be added to each * `:max_jitter` - Maximum amount of time in milliseconds to be added to each
wait before multiplied by timeout count wait before multiplied by timeout count
* `:throttle_rolling_window_opts` - Options for the process tracking all requests * `:throttle_rolling_window_opts` - Options for the process tracking all requests
* `:window_count` - Number of windows * `:window_count` - Number of windows
* `:duration` - Total amount of time to coumt events in milliseconds * `:duration` - Total amount of time to count events in milliseconds
* `:table` - name of the ets table to store the data in * `:table` - name of the ets table to store the data in
* `:throttle_rate_limit` - The total number of requests allowed in the all windows. * `:throttle_rate_limit` - The total number of requests allowed in the all windows.

@ -8,7 +8,7 @@ defmodule EthereumJSONRPC.RollingWindowTest do
end end
describe "init/1" do describe "init/1" do
test "raises when duration isn't evenly divisble by window_count" do test "raises when duration isn't evenly divisible by window_count" do
assert_raise ArgumentError, ~r"evenly divisible", fn -> assert_raise ArgumentError, ~r"evenly divisible", fn ->
RollingWindow.init(table: :init_test_table, duration: :timer.seconds(2), window_count: 3) RollingWindow.init(table: :init_test_table, duration: :timer.seconds(2), window_count: 3)
end end

@ -235,7 +235,7 @@ defmodule EthereumJSONRPCTest do
describe "fetch_beneficiaries/2" do describe "fetch_beneficiaries/2" do
@tag :no_geth @tag :no_geth
test "fetches benefeciaries from variant API", %{json_rpc_named_arguments: json_rpc_named_arguments} do test "fetches beneficiaries from variant API", %{json_rpc_named_arguments: json_rpc_named_arguments} do
if json_rpc_named_arguments[:transport] == EthereumJSONRPC.Mox do if json_rpc_named_arguments[:transport] == EthereumJSONRPC.Mox do
expect(EthereumJSONRPC.Mox, :json_rpc, fn _, _ -> expect(EthereumJSONRPC.Mox, :json_rpc, fn _, _ ->
{:ok, []} {:ok, []}

@ -41,7 +41,7 @@ defmodule Explorer.Account.TagAddress do
|> validate_length(:name, min: 1, max: 35) |> validate_length(:name, min: 1, max: 35)
|> put_hashed_fields() |> put_hashed_fields()
|> unique_constraint([:identity_id, :address_hash_hash], message: "Address tag already exists") |> unique_constraint([:identity_id, :address_hash_hash], message: "Address tag already exists")
|> check_existance_or_create_address() |> check_existence_or_create_address()
|> tag_address_count_constraint() |> tag_address_count_constraint()
end end
@ -56,13 +56,13 @@ defmodule Explorer.Account.TagAddress do
|> put_change(:address_hash_hash, hash_to_lower_case_string(get_field(changeset, :address_hash))) |> put_change(:address_hash_hash, hash_to_lower_case_string(get_field(changeset, :address_hash)))
end end
defp check_existance_or_create_address(%Changeset{changes: %{address_hash: address_hash}, valid?: true} = changeset) do defp check_existence_or_create_address(%Changeset{changes: %{address_hash: address_hash}, valid?: true} = changeset) do
check_existance_or_create_address_inner(changeset, address_hash) check_existence_or_create_address_inner(changeset, address_hash)
end end
defp check_existance_or_create_address(changeset), do: changeset defp check_existence_or_create_address(changeset), do: changeset
defp check_existance_or_create_address_inner(changeset, address_hash) do defp check_existence_or_create_address_inner(changeset, address_hash) do
with {:ok, hash} <- Hash.Address.cast(address_hash), with {:ok, hash} <- Hash.Address.cast(address_hash),
{:ok, %Address{}} <- Chain.find_or_insert_address_from_hash(hash, []) do {:ok, %Address{}} <- Chain.find_or_insert_address_from_hash(hash, []) do
changeset changeset

@ -40,7 +40,7 @@ defmodule Explorer.Account.TagTransaction do
|> put_hashed_fields() |> put_hashed_fields()
|> unique_constraint([:identity_id, :tx_hash_hash], message: "Transaction tag already exists") |> unique_constraint([:identity_id, :tx_hash_hash], message: "Transaction tag already exists")
|> tag_transaction_count_constraint() |> tag_transaction_count_constraint()
|> check_transaction_existance() |> check_transaction_existence()
end end
def create(attrs) do def create(attrs) do
@ -54,13 +54,13 @@ defmodule Explorer.Account.TagTransaction do
|> put_change(:tx_hash_hash, hash_to_lower_case_string(get_field(changeset, :tx_hash))) |> put_change(:tx_hash_hash, hash_to_lower_case_string(get_field(changeset, :tx_hash)))
end end
defp check_transaction_existance(%Changeset{changes: %{tx_hash: tx_hash}} = changeset) do defp check_transaction_existence(%Changeset{changes: %{tx_hash: tx_hash}} = changeset) do
check_transaction_existance_inner(changeset, tx_hash) check_transaction_existence_inner(changeset, tx_hash)
end end
defp check_transaction_existance(changeset), do: changeset defp check_transaction_existence(changeset), do: changeset
defp check_transaction_existance_inner(changeset, tx_hash) do defp check_transaction_existence_inner(changeset, tx_hash) do
if match?({:ok, _}, Chain.hash_to_transaction(tx_hash)) do if match?({:ok, _}, Chain.hash_to_transaction(tx_hash)) do
changeset changeset
else else

@ -1,6 +1,6 @@
defmodule Explorer.Account.WatchlistNotification do defmodule Explorer.Account.WatchlistNotification do
@moduledoc """ @moduledoc """
Strored notification about event Stored notification about event
related to WatchlistAddress related to WatchlistAddress
""" """

@ -98,7 +98,7 @@ defmodule Explorer.Chain do
@default_paging_options %PagingOptions{page_size: 50} @default_paging_options %PagingOptions{page_size: 50}
@token_transfers_per_transaction_preview 10 @token_transfers_per_transaction_preview 10
@token_transfers_neccessity_by_association %{ @token_transfers_necessity_by_association %{
[from_address: :smart_contract] => :optional, [from_address: :smart_contract] => :optional,
[to_address: :smart_contract] => :optional, [to_address: :smart_contract] => :optional,
[from_address: :names] => :optional, [from_address: :names] => :optional,
@ -346,7 +346,7 @@ defmodule Explorer.Chain do
This query is divided into multiple subqueries intentionally in order to This query is divided into multiple subqueries intentionally in order to
improve the listing performance. improve the listing performance.
The `token_trasfers` table tends to grow exponentially, and the query results The `token_transfers` table tends to grow exponentially, and the query results
with a `transactions` `join` statement takes too long. with a `transactions` `join` statement takes too long.
To solve this the `transaction_hashes` are fetched in a separate query, and To solve this the `transaction_hashes` are fetched in a separate query, and
@ -473,7 +473,7 @@ defmodule Explorer.Chain do
options options
|> address_to_transactions_tasks_query() |> address_to_transactions_tasks_query()
|> Transaction.not_dropped_or_replaced_transacions() |> Transaction.not_dropped_or_replaced_transactions()
|> where_block_number_in_period(from_block, to_block) |> where_block_number_in_period(from_block, to_block)
|> join_associations(necessity_by_association) |> join_associations(necessity_by_association)
|> Transaction.matching_address_queries_list(direction, address_hash) |> Transaction.matching_address_queries_list(direction, address_hash)
@ -967,7 +967,7 @@ defmodule Explorer.Chain do
|> Repo.all() |> Repo.all()
|> (&if(old_ui?, |> (&if(old_ui?,
do: &1, do: &1,
else: Enum.map(&1, fn tx -> preload_token_transfers(tx, @token_transfers_neccessity_by_association) end) else: Enum.map(&1, fn tx -> preload_token_transfers(tx, @token_transfers_necessity_by_association) end)
)).() )).()
end end
@ -2087,7 +2087,7 @@ defmodule Explorer.Chain do
end end
end end
# preload_to_detect_tt?: we don't need to preload more than one token transfer in case the tx inside the list (we dont't show any token transfers on tx tile in new UI) # preload_to_detect_tt?: we don't need to preload more than one token transfer in case the tx inside the list (we don't show any token transfers on tx tile in new UI)
def preload_token_transfers( def preload_token_transfers(
%Transaction{hash: tx_hash, block_hash: block_hash} = transaction, %Transaction{hash: tx_hash, block_hash: block_hash} = transaction,
necessity_by_association, necessity_by_association,
@ -3402,7 +3402,7 @@ defmodule Explorer.Chain do
|> Repo.all() |> Repo.all()
|> (&if(old_ui?, |> (&if(old_ui?,
do: &1, do: &1,
else: Enum.map(&1, fn tx -> preload_token_transfers(tx, @token_transfers_neccessity_by_association) end) else: Enum.map(&1, fn tx -> preload_token_transfers(tx, @token_transfers_necessity_by_association) end)
)).() )).()
end end
@ -3452,7 +3452,7 @@ defmodule Explorer.Chain do
|> Repo.all() |> Repo.all()
|> (&if(old_ui?, |> (&if(old_ui?,
do: &1, do: &1,
else: Enum.map(&1, fn tx -> preload_token_transfers(tx, @token_transfers_neccessity_by_association) end) else: Enum.map(&1, fn tx -> preload_token_transfers(tx, @token_transfers_necessity_by_association) end)
)).() )).()
end end
@ -4470,7 +4470,7 @@ defmodule Explorer.Chain do
defp handle_random_access_paging_options(query, paging_options) do defp handle_random_access_paging_options(query, paging_options) do
query query
|> (&if(paging_options |> Map.get(:page_number, 1) |> proccess_page_number() == 1, |> (&if(paging_options |> Map.get(:page_number, 1) |> process_page_number() == 1,
do: &1, do: &1,
else: page_transaction(&1, paging_options) else: page_transaction(&1, paging_options)
)).() )).()
@ -4478,7 +4478,7 @@ defmodule Explorer.Chain do
end end
defp handle_page(query, paging_options) do defp handle_page(query, paging_options) do
page_number = paging_options |> Map.get(:page_number, 1) |> proccess_page_number() page_number = paging_options |> Map.get(:page_number, 1) |> process_page_number()
page_size = Map.get(paging_options, :page_size, @default_page_size) page_size = Map.get(paging_options, :page_size, @default_page_size)
cond do cond do
@ -4497,9 +4497,9 @@ defmodule Explorer.Chain do
end end
end end
defp proccess_page_number(number) when number < 1, do: 1 defp process_page_number(number) when number < 1, do: 1
defp proccess_page_number(number), do: number defp process_page_number(number), do: number
defp page_in_bounds?(page_number, page_size), defp page_in_bounds?(page_number, page_size),
do: page_size <= @limit_showing_transactions && @limit_showing_transactions - page_number * page_size >= 0 do: page_size <= @limit_showing_transactions && @limit_showing_transactions - page_number * page_size >= 0

@ -1,7 +1,7 @@
defmodule Explorer.Chain.Address.CoinBalanceDaily do defmodule Explorer.Chain.Address.CoinBalanceDaily do
@moduledoc """ @moduledoc """
Maximum `t:Explorer.Chain.Wei.t/0` `value` of `t:Explorer.Chain.Address.t/0` at the day. Maximum `t:Explorer.Chain.Wei.t/0` `value` of `t:Explorer.Chain.Address.t/0` at the day.
This table is used to display coinn balance history chart. This table is used to display coin balance history chart.
""" """
use Explorer.Schema use Explorer.Schema

@ -2,7 +2,7 @@ defmodule Explorer.Chain.Address.TokenBalance do
@moduledoc """ @moduledoc """
Represents a token balance from an address. Represents a token balance from an address.
In this table we can see all token balances that a specific addreses had acording to the block In this table we can see all token balances that a specific addresses had according to the block
numbers. If you want to show only the last balance from an address, consider querying against numbers. If you want to show only the last balance from an address, consider querying against
`Address.CurrentTokenBalance` instead. `Address.CurrentTokenBalance` instead.
""" """

@ -34,7 +34,7 @@ defmodule Explorer.Chain.Cache.Accounts do
def drop([]), do: :ok def drop([]), do: :ok
def drop(addresses) when is_list(addresses) do def drop(addresses) when is_list(addresses) do
# This has to be used by the Indexer insead of `update`. # This has to be used by the Indexer instead of `update`.
# The reason being that addresses already in the cache can change their balance # The reason being that addresses already in the cache can change their balance
# value and removing or updating them will result into a potentially invalid # value and removing or updating them will result into a potentially invalid
# cache status, that would not even get corrected with time. # cache status, that would not even get corrected with time.

@ -35,7 +35,7 @@ defmodule Explorer.Chain.Cache.AddressSum do
rescue rescue
e -> e ->
Logger.debug([ Logger.debug([
"Coudn't update address sum: ", "Couldn't update address sum: ",
Exception.format(:error, e, __STACKTRACE__) Exception.format(:error, e, __STACKTRACE__)
]) ])
end end

@ -42,7 +42,7 @@ defmodule Explorer.Chain.Cache.AddressSumMinusBurnt do
rescue rescue
e -> e ->
Logger.debug([ Logger.debug([
"Coudn't update address sum: ", "Couldn't update address sum: ",
Exception.format(:error, e, __STACKTRACE__) Exception.format(:error, e, __STACKTRACE__)
]) ])
end end

@ -59,7 +59,7 @@ defmodule Explorer.Chain.Cache.Block do
rescue rescue
e -> e ->
Logger.debug([ Logger.debug([
"Coudn't update block count: ", "Couldn't update block count: ",
Exception.format(:error, e, __STACKTRACE__) Exception.format(:error, e, __STACKTRACE__)
]) ])
end end

@ -46,7 +46,7 @@ defmodule Explorer.Chain.Cache.GasPriceOracle do
callback: &async_task_on_deletion(&1) callback: &async_task_on_deletion(&1)
def get_average_gas_price(num_of_blocks, safelow_percentile, average_percentile, fast_percentile) do def get_average_gas_price(num_of_blocks, safelow_percentile, average_percentile, fast_percentile) do
lates_gas_price_query = latest_gas_price_query =
from( from(
block in Block, block in Block,
left_join: transaction in assoc(block, :transactions), left_join: transaction in assoc(block, :transactions),
@ -60,7 +60,7 @@ defmodule Explorer.Chain.Cache.GasPriceOracle do
) )
latest_gas_prices = latest_gas_prices =
lates_gas_price_query latest_gas_price_query
|> Repo.all(timeout: :infinity) |> Repo.all(timeout: :infinity)
latest_ordered_gas_prices = latest_ordered_gas_prices =
@ -103,7 +103,7 @@ defmodule Explorer.Chain.Cache.GasPriceOracle do
rescue rescue
e -> e ->
Logger.debug([ Logger.debug([
"Coudn't update gas used gas_prices", "Couldn't update gas used gas_prices",
Exception.format(:error, e, __STACKTRACE__) Exception.format(:error, e, __STACKTRACE__)
]) ])
end end

@ -57,7 +57,7 @@ defmodule Explorer.Chain.Cache.GasUsage do
rescue rescue
e -> e ->
Logger.debug([ Logger.debug([
"Coudn't update gas used sum: ", "Couldn't update gas used sum: ",
Exception.format(:error, e, __STACKTRACE__) Exception.format(:error, e, __STACKTRACE__)
]) ])
end end

@ -16,7 +16,7 @@ defmodule Explorer.Chain.Cache.NetVersion do
{:error, reason} -> {:error, reason} ->
Logger.debug([ Logger.debug([
"Coudn't fetch net_version, reason: #{inspect(reason)}" "Couldn't fetch net_version, reason: #{inspect(reason)}"
]) ])
{:return, nil} {:return, nil}

@ -1,6 +1,6 @@
defmodule Explorer.Chain.Cache.NewVerifiedContractsCounter do defmodule Explorer.Chain.Cache.NewVerifiedContractsCounter do
@moduledoc """ @moduledoc """
Caches the number of new verfied contracts (verified in last 24 hours). Caches the number of new verified contracts (verified in last 24 hours).
It loads the count asynchronously and in a time interval of 30 minutes. It loads the count asynchronously and in a time interval of 30 minutes.
""" """

@ -56,7 +56,7 @@ defmodule Explorer.Chain.Cache.Transaction do
rescue rescue
e -> e ->
Logger.debug([ Logger.debug([
"Coudn't update transaction count: ", "Couldn't update transaction count: ",
Exception.format(:error, e, __STACKTRACE__) Exception.format(:error, e, __STACKTRACE__)
]) ])
end end

@ -12,7 +12,7 @@ defmodule Explorer.Chain.Import.Runner do
@typedoc """ @typedoc """
Validated changes extracted from a valid `Ecto.Changeset` produced by the `t:changeset_function_name/0` in Validated changes extracted from a valid `Ecto.Changeset` produced by the `t:changeset_function_name/0` in
`c:ecto_schemma_module/0`. `c:ecto_schema_module/0`.
""" """
@type changes :: %{optional(atom) => term()} @type changes :: %{optional(atom) => term()}

@ -112,7 +112,7 @@ defmodule Explorer.Chain.Import.Runner.Address.CurrentTokenBalances do
token_contract_address_hashes_and_ids = token_contract_address_hashes_and_ids =
changes_list changes_list
|> Enum.map(fn change -> |> Enum.map(fn change ->
token_id = get_tokend_id(change) token_id = get_token_id(change)
{change.token_contract_address_hash, token_id} {change.token_contract_address_hash, token_id}
end) end)
@ -161,7 +161,7 @@ defmodule Explorer.Chain.Import.Runner.Address.CurrentTokenBalances do
end) end)
end end
defp get_tokend_id(change) do defp get_token_id(change) do
if Map.has_key?(change, :token_id), do: change.token_id, else: nil if Map.has_key?(change, :token_id), do: change.token_id, else: nil
end end

@ -46,7 +46,7 @@ defmodule Explorer.Chain.Import.Runner.Address.TokenBalances do
Instrumenter.block_import_stage_runner( Instrumenter.block_import_stage_runner(
fn -> insert(repo, changes_list, insert_options) end, fn -> insert(repo, changes_list, insert_options) end,
:block_referencing, :block_referencing,
:token_blances, :token_balances,
:address_token_balances :address_token_balances
) )
end) end)

@ -369,7 +369,7 @@ defmodule Explorer.Chain.Import.Runner.Blocks do
}) do }) do
acquire_query = acquire_query =
from( from(
block in where_invalid_neighbour(changes_list), block in where_invalid_neighbor(changes_list),
or_where: block.number in ^consensus_block_numbers, or_where: block.number in ^consensus_block_numbers,
# we also need to acquire blocks that will be upserted here, for ordering # we also need to acquire blocks that will be upserted here, for ordering
or_where: block.hash in ^hashes, or_where: block.hash in ^hashes,
@ -711,7 +711,7 @@ defmodule Explorer.Chain.Import.Runner.Blocks do
end) end)
end end
defp where_invalid_neighbour(blocks_changes) when is_list(blocks_changes) do defp where_invalid_neighbor(blocks_changes) when is_list(blocks_changes) do
initial = from(b in Block, where: false) initial = from(b in Block, where: false)
Enum.reduce(blocks_changes, initial, fn %{ Enum.reduce(blocks_changes, initial, fn %{

@ -678,7 +678,7 @@ defmodule Explorer.Chain.Import.Runner.InternalTransactions do
) )
try do try do
# ShreLocks order already enforced by `acquire_pending_internal_txs` (see docs: sharelocks.md) # ShareLocks order already enforced by `acquire_pending_internal_txs` (see docs: sharelocks.md)
{_count, deleted} = repo.delete_all(delete_query, []) {_count, deleted} = repo.delete_all(delete_query, [])
{:ok, deleted} {:ok, deleted}

@ -200,7 +200,7 @@ defmodule Explorer.Chain.InternalTransaction do
bytes: <<120, 164, 45, 55, 5, 251, 60, 38, 164, 181, 71, 55, 167, 132, 191, 6, 79, 8, 21, 251>> bytes: <<120, 164, 45, 55, 5, 251, 60, 38, 164, 181, 71, 55, 167, 132, 191, 6, 79, 8, 21, 251>>
} }
`:call` type traces are generated when a method in a contrat is call. `:call` type traces are generated when a method in a contract is call.
iex> changeset = Explorer.Chain.InternalTransaction.changeset( iex> changeset = Explorer.Chain.InternalTransaction.changeset(
...> %Explorer.Chain.InternalTransaction{}, ...> %Explorer.Chain.InternalTransaction{},
@ -608,7 +608,7 @@ defmodule Explorer.Chain.InternalTransaction do
end end
@doc """ @doc """
Filters out internal_transactions of blocks that are flagged as needing fethching Filters out internal_transactions of blocks that are flagged as needing fetching
of internal_transactions of internal_transactions
""" """
def where_nonpending_block(query \\ nil) do def where_nonpending_block(query \\ nil) do

@ -28,7 +28,7 @@ defmodule Explorer.Chain.MapCache do
## Callbacks ## Callbacks
Apart from the `callback` that can be set as part of the `ConCache` options, Apart from the `callback` that can be set as part of the `ConCache` options,
two callbacks esist and can be overridden: two callbacks exist and can be overridden:
`c:handle_update/3` will be called whenever an update is issued. It will receive `c:handle_update/3` will be called whenever an update is issued. It will receive
the `t:key/0` that is going to be updated, the current `t:value/0` that is the `t:key/0` that is going to be updated, the current `t:value/0` that is

@ -246,7 +246,7 @@ defmodule Explorer.Chain.OrderedCache do
defp merge_and_update([], existing, size) do defp merge_and_update([], existing, size) do
# if there are no more candidates to be inserted keep as many of the # if there are no more candidates to be inserted keep as many of the
# exsisting elements and remove the rest # existing elements and remove the rest
{remaining, to_remove} = Enum.split(existing, size) {remaining, to_remove} = Enum.split(existing, size)
remove(to_remove) remove(to_remove)
remaining remaining
@ -274,7 +274,7 @@ defmodule Explorer.Chain.OrderedCache do
[head | merge_and_update(to_check, tail, size - 1)] [head | merge_and_update(to_check, tail, size - 1)]
prevails?(head, candidate_id) -> prevails?(head, candidate_id) ->
# keep the prevaling existing value and compare all candidates against the rest # keep the prevailing existing value and compare all candidates against the rest
[head | merge_and_update(candidates, tail, size - 1)] [head | merge_and_update(candidates, tail, size - 1)]
true -> true ->

@ -544,7 +544,7 @@ defmodule Explorer.Chain.SmartContract do
) do ) do
updated_smart_contract = updated_smart_contract =
if Application.get_env(:explorer, :enable_caching_implementation_data_of_proxy) && if Application.get_env(:explorer, :enable_caching_implementation_data_of_proxy) &&
check_implementation_refetch_neccessity(implementation_fetched_at) do check_implementation_refetch_necessity(implementation_fetched_at) do
Chain.address_hash_to_smart_contract_without_twin(address_hash) Chain.address_hash_to_smart_contract_without_twin(address_hash)
else else
smart_contract smart_contract
@ -564,7 +564,7 @@ defmodule Explorer.Chain.SmartContract do
metadata_from_verified_twin: metadata_from_verified_twin metadata_from_verified_twin: metadata_from_verified_twin
}} }}
) do ) do
if check_implementation_refetch_neccessity(implementation_fetched_at) do if check_implementation_refetch_necessity(implementation_fetched_at) do
get_implementation_address_hash_task = get_implementation_address_hash_task =
Task.async(fn -> get_implementation_address_hash(address_hash, abi, metadata_from_verified_twin) end) Task.async(fn -> get_implementation_address_hash(address_hash, abi, metadata_from_verified_twin) end)
@ -594,9 +594,9 @@ defmodule Explorer.Chain.SmartContract do
defp db_implementation_data_converter(string) when is_binary(string), do: string defp db_implementation_data_converter(string) when is_binary(string), do: string
defp db_implementation_data_converter(other), do: to_string(other) defp db_implementation_data_converter(other), do: to_string(other)
defp check_implementation_refetch_neccessity(nil), do: true defp check_implementation_refetch_necessity(nil), do: true
defp check_implementation_refetch_neccessity(timestamp) do defp check_implementation_refetch_necessity(timestamp) do
if Application.get_env(:explorer, :enable_caching_implementation_data_of_proxy) do if Application.get_env(:explorer, :enable_caching_implementation_data_of_proxy) do
now = DateTime.utc_now() now = DateTime.utc_now()

@ -13,7 +13,7 @@ defmodule Explorer.Chain.SmartContract.VerificationStatus do
@typedoc """ @typedoc """
* `address_hash` - address of the contract which was tried to verify * `address_hash` - address of the contract which was tried to verify
* `status` - try status: :pending | :pass | :fail * `status` - try status: :pending | :pass | :fail
* `uid` - unique verification try identifer * `uid` - unique verification try identifier
""" """
@type t :: %__MODULE__{ @type t :: %__MODULE__{

@ -108,9 +108,9 @@ defmodule Explorer.Chain.Supply.RSK do
%{block_quantity: integer_to_quantity(max_number), hash_data: "0x0000000000000000000000000000000001000006"} %{block_quantity: integer_to_quantity(max_number), hash_data: "0x0000000000000000000000000000000001000006"}
] ]
json_rpc_named_argumens = Application.get_env(:explorer, :json_rpc_named_arguments) json_rpc_named_arguments = Application.get_env(:explorer, :json_rpc_named_arguments)
case EthereumJSONRPC.fetch_balances(params, json_rpc_named_argumens) do case EthereumJSONRPC.fetch_balances(params, json_rpc_named_arguments) do
{:ok, {:ok,
%FetchedBalances{ %FetchedBalances{
errors: [], errors: [],

@ -32,7 +32,7 @@ defmodule Explorer.Chain.Token do
* `total_supply` - The total supply of the token * `total_supply` - The total supply of the token
* `decimals` - Number of decimal places the token can be subdivided to * `decimals` - Number of decimal places the token can be subdivided to
* `type` - Type of token * `type` - Type of token
* `calatoged` - Flag for if token information has been cataloged * `cataloged` - Flag for if token information has been cataloged
* `contract_address` - The `t:Address.t/0` of the token's contract * `contract_address` - The `t:Address.t/0` of the token's contract
* `contract_address_hash` - Address hash foreign key * `contract_address_hash` - Address hash foreign key
* `holder_count` - the number of `t:Explorer.Chain.Address.t/0` (except the burn address) that have a * `holder_count` - the number of `t:Explorer.Chain.Address.t/0` (except the burn address) that have a

@ -446,14 +446,14 @@ defmodule Explorer.Chain.Transaction do
def decoded_revert_reason(transaction, revert_reason) do def decoded_revert_reason(transaction, revert_reason) do
case revert_reason do case revert_reason do
"0x" <> hex_part -> "0x" <> hex_part ->
proccess_hex_revert_reason(hex_part, transaction) process_hex_revert_reason(hex_part, transaction)
hex_part -> hex_part ->
proccess_hex_revert_reason(hex_part, transaction) process_hex_revert_reason(hex_part, transaction)
end end
end end
defp proccess_hex_revert_reason(hex_revert_reason, %__MODULE__{to_address: smart_contract, hash: hash}) do defp process_hex_revert_reason(hex_revert_reason, %__MODULE__{to_address: smart_contract, hash: hash}) do
case Integer.parse(hex_revert_reason, 16) do case Integer.parse(hex_revert_reason, 16) do
{number, ""} -> {number, ""} ->
binary_revert_reason = :binary.encode_unsigned(number) binary_revert_reason = :binary.encode_unsigned(number)
@ -734,7 +734,7 @@ defmodule Explorer.Chain.Transaction do
where(query, [t], not is_nil(t.block_number)) where(query, [t], not is_nil(t.block_number))
end end
def not_dropped_or_replaced_transacions(query) do def not_dropped_or_replaced_transactions(query) do
where(query, [t], is_nil(t.error) or t.error != "dropped/replaced") where(query, [t], is_nil(t.error) or t.error != "dropped/replaced")
end end

@ -1,6 +1,6 @@
defmodule Explorer.Chain.Transaction.History.Historian do defmodule Explorer.Chain.Transaction.History.Historian do
@moduledoc """ @moduledoc """
Implements behaviour Historian which will compile TransactionStats from Block/Transaction data and then save the TransactionStats into the database for later retrevial. Implements behaviour Historian which will compile TransactionStats from Block/Transaction data and then save the TransactionStats into the database for later retrieval.
""" """
require Logger require Logger
use Explorer.History.Historian use Explorer.History.Historian

@ -1,6 +1,6 @@
defmodule Explorer.EnvVarTranslator do defmodule Explorer.EnvVarTranslator do
@moduledoc """ @moduledoc """
The module for transaformation of environment variables The module for transformation of environment variables
""" """
alias Poison.Parser alias Poison.Parser

@ -4,7 +4,7 @@ defmodule Explorer.Repo.ConfigHelper do
Notably, this module processes the DATABASE_URL environment variable and extracts discrete parameters. Notably, this module processes the DATABASE_URL environment variable and extracts discrete parameters.
The priority of vars is postgrex environment vars < DATABASE_URL components, with values being overwritted by higher priority. The priority of vars is postgrex environment vars < DATABASE_URL components, with values being overwritten by higher priority.
""" """
# https://hexdocs.pm/postgrex/Postgrex.html#start_link/1-options # https://hexdocs.pm/postgrex/Postgrex.html#start_link/1-options

@ -360,7 +360,7 @@ defmodule Explorer.SmartContract.Reader do
@doc """ @doc """
Method performs query of read functions of a smart contract. Method performs query of read functions of a smart contract.
`type` could be :proxy or :reqular `type` could be :proxy or :regular
`from` is a address of a function caller `from` is a address of a function caller
""" """
@spec query_function_with_names( @spec query_function_with_names(
@ -377,7 +377,7 @@ defmodule Explorer.SmartContract.Reader do
@doc """ @doc """
Method performs query of read functions of a smart contract. Method performs query of read functions of a smart contract.
`type` could be :proxy or :reqular `type` could be :proxy or :regular
`from` is a address of a function caller `from` is a address of a function caller
""" """
@spec query_function_with_names_custom_abi( @spec query_function_with_names_custom_abi(
@ -427,7 +427,7 @@ defmodule Explorer.SmartContract.Reader do
abi abi
|> ABI.parse_specification() |> ABI.parse_specification()
case proccess_abi(parsed_final_abi, method_id) do case process_abi(parsed_final_abi, method_id) do
%{outputs: outputs, method_id: method_id} -> %{outputs: outputs, method_id: method_id} ->
query_contract_and_link_outputs(contract_address_hash, args, from, abi, outputs, method_id, leave_error_as_map) query_contract_and_link_outputs(contract_address_hash, args, from, abi, outputs, method_id, leave_error_as_map)
@ -493,7 +493,7 @@ defmodule Explorer.SmartContract.Reader do
custom_abi custom_abi
|> ABI.parse_specification() |> ABI.parse_specification()
%{outputs: outputs, method_id: method_id} = proccess_abi(parsed_abi, method_id) %{outputs: outputs, method_id: method_id} = process_abi(parsed_abi, method_id)
query_contract_and_link_outputs( query_contract_and_link_outputs(
contract_address_hash, contract_address_hash,
@ -506,9 +506,9 @@ defmodule Explorer.SmartContract.Reader do
) )
end end
defp proccess_abi([], _method_id), do: nil defp process_abi([], _method_id), do: nil
defp proccess_abi(abi, method_id) do defp process_abi(abi, method_id) do
function_object = find_function_by_method(abi, method_id) function_object = find_function_by_method(abi, method_id)
if function_object do if function_object do

@ -50,7 +50,7 @@ defmodule Explorer.SmartContract.RustVerifierInterface do
case HTTPoison.post(url, Jason.encode!(normalize_creation_bytecode(body)), headers, recv_timeout: @post_timeout) do case HTTPoison.post(url, Jason.encode!(normalize_creation_bytecode(body)), headers, recv_timeout: @post_timeout) do
{:ok, %Response{body: body, status_code: _}} -> {:ok, %Response{body: body, status_code: _}} ->
proccess_verifier_response(body) process_verifier_response(body)
{:error, error} -> {:error, error} ->
old_truncate = Application.get_env(:logger, :truncate) old_truncate = Application.get_env(:logger, :truncate)
@ -71,7 +71,7 @@ defmodule Explorer.SmartContract.RustVerifierInterface do
def http_get_request(url) do def http_get_request(url) do
case HTTPoison.get(url) do case HTTPoison.get(url) do
{:ok, %Response{body: body, status_code: 200}} -> {:ok, %Response{body: body, status_code: 200}} ->
proccess_verifier_response(body) process_verifier_response(body)
{:ok, %Response{body: body, status_code: _}} -> {:ok, %Response{body: body, status_code: _}} ->
{:error, body} {:error, body}
@ -100,27 +100,27 @@ defmodule Explorer.SmartContract.RustVerifierInterface do
http_get_request(vyper_versions_list_url()) http_get_request(vyper_versions_list_url())
end end
def proccess_verifier_response(body) when is_binary(body) do def process_verifier_response(body) when is_binary(body) do
case Jason.decode(body) do case Jason.decode(body) do
{:ok, decoded} -> {:ok, decoded} ->
proccess_verifier_response(decoded) process_verifier_response(decoded)
_ -> _ ->
{:error, body} {:error, body}
end end
end end
def proccess_verifier_response(%{"status" => "SUCCESS", "source" => source}) do def process_verifier_response(%{"status" => "SUCCESS", "source" => source}) do
{:ok, source} {:ok, source}
end end
def proccess_verifier_response(%{"status" => "FAILURE", "message" => error}) do def process_verifier_response(%{"status" => "FAILURE", "message" => error}) do
{:error, error} {:error, error}
end end
def proccess_verifier_response(%{"compilerVersions" => versions}), do: {:ok, versions} def process_verifier_response(%{"compilerVersions" => versions}), do: {:ok, versions}
def proccess_verifier_response(other), do: {:error, other} def process_verifier_response(other), do: {:error, other}
def normalize_creation_bytecode(%{"creation_bytecode" => ""} = map), do: Map.replace(map, "creation_bytecode", nil) def normalize_creation_bytecode(%{"creation_bytecode" => ""} = map), do: Map.replace(map, "creation_bytecode", nil)

@ -39,7 +39,7 @@ defmodule Explorer.SmartContract.SigProviderInterface do
def http_get_request(url) do def http_get_request(url) do
case HTTPoison.get(url) do case HTTPoison.get(url) do
{:ok, %Response{body: body, status_code: 200}} -> {:ok, %Response{body: body, status_code: 200}} ->
proccess_sig_provider_response(body) process_sig_provider_response(body)
{:ok, %Response{body: body, status_code: _}} -> {:ok, %Response{body: body, status_code: _}} ->
{:error, body} {:error, body}
@ -60,19 +60,19 @@ defmodule Explorer.SmartContract.SigProviderInterface do
end end
end end
def proccess_sig_provider_response(body) when is_binary(body) do def process_sig_provider_response(body) when is_binary(body) do
case Jason.decode(body) do case Jason.decode(body) do
{:ok, decoded} -> {:ok, decoded} ->
proccess_sig_provider_response(decoded) process_sig_provider_response(decoded)
_ -> _ ->
{:error, body} {:error, body}
end end
end end
def proccess_sig_provider_response(results) when is_list(results), do: {:ok, results} def process_sig_provider_response(results) when is_list(results), do: {:ok, results}
def proccess_sig_provider_response(other_responses), do: {:error, other_responses} def process_sig_provider_response(other_responses), do: {:error, other_responses}
def tx_input_decode_url, do: "#{base_api_url()}" <> "/function" def tx_input_decode_url, do: "#{base_api_url()}" <> "/function"

@ -181,19 +181,19 @@ defmodule Explorer.SmartContract.Solidity.PublishHelper do
def publish_without_broadcast( def publish_without_broadcast(
%{"addressHash" => address_hash, "abi" => abi, "compilationTargetFilePath" => file_path} = input %{"addressHash" => address_hash, "abi" => abi, "compilationTargetFilePath" => file_path} = input
) do ) do
params = proccess_params(input) params = process_params(input)
address_hash address_hash
|> Publisher.publish_smart_contract(params, abi, file_path) |> Publisher.publish_smart_contract(params, abi, file_path)
|> proccess_response() |> process_response()
end end
def publish_without_broadcast(%{"addressHash" => address_hash, "abi" => abi} = input) do def publish_without_broadcast(%{"addressHash" => address_hash, "abi" => abi} = input) do
params = proccess_params(input) params = process_params(input)
address_hash address_hash
|> Publisher.publish_smart_contract(params, abi) |> Publisher.publish_smart_contract(params, abi)
|> proccess_response() |> process_response()
end end
def publish(nil, %{"addressHash" => _address_hash} = input, _) do def publish(nil, %{"addressHash" => _address_hash} = input, _) do
@ -210,7 +210,7 @@ defmodule Explorer.SmartContract.Solidity.PublishHelper do
end end
end end
def proccess_params(input) do def process_params(input) do
if Map.has_key?(input, "secondarySources") do if Map.has_key?(input, "secondarySources") do
input["params"] input["params"]
|> Map.put("secondary_sources", Map.get(input, "secondarySources")) |> Map.put("secondary_sources", Map.get(input, "secondarySources"))
@ -219,7 +219,7 @@ defmodule Explorer.SmartContract.Solidity.PublishHelper do
end end
end end
def proccess_response(response) do def process_response(response) do
case response do case response do
{:ok, _contract} = result -> {:ok, _contract} = result ->
result result

@ -27,9 +27,9 @@ defmodule Explorer.SmartContract.Solidity.Publisher do
""" """
def publish(address_hash, params, external_libraries \\ %{}) do def publish(address_hash, params, external_libraries \\ %{}) do
params_with_external_libaries = add_external_libraries(params, external_libraries) params_with_external_libraries = add_external_libraries(params, external_libraries)
case Verifier.evaluate_authenticity(address_hash, params_with_external_libaries) do case Verifier.evaluate_authenticity(address_hash, params_with_external_libraries) do
{ {
:ok, :ok,
%{ %{
@ -42,25 +42,25 @@ defmodule Explorer.SmartContract.Solidity.Publisher do
"sourceFiles" => _ "sourceFiles" => _
} = result_params } = result_params
} -> } ->
proccess_rust_verifier_response(result_params, address_hash, false, false) process_rust_verifier_response(result_params, address_hash, false, false)
{:ok, %{abi: abi, constructor_arguments: constructor_arguments}} -> {:ok, %{abi: abi, constructor_arguments: constructor_arguments}} ->
params_with_constructor_arguments = params_with_constructor_arguments =
Map.put(params_with_external_libaries, "constructor_arguments", constructor_arguments) Map.put(params_with_external_libraries, "constructor_arguments", constructor_arguments)
publish_smart_contract(address_hash, params_with_constructor_arguments, abi) publish_smart_contract(address_hash, params_with_constructor_arguments, abi)
{:ok, %{abi: abi}} -> {:ok, %{abi: abi}} ->
publish_smart_contract(address_hash, params_with_external_libaries, abi) publish_smart_contract(address_hash, params_with_external_libraries, abi)
{:error, error} -> {:error, error} ->
{:error, unverified_smart_contract(address_hash, params_with_external_libaries, error, nil)} {:error, unverified_smart_contract(address_hash, params_with_external_libraries, error, nil)}
{:error, error, error_message} -> {:error, error, error_message} ->
{:error, unverified_smart_contract(address_hash, params_with_external_libaries, error, error_message)} {:error, unverified_smart_contract(address_hash, params_with_external_libraries, error, error_message)}
_ -> _ ->
{:error, unverified_smart_contract(address_hash, params_with_external_libaries, "Unexpected error", nil)} {:error, unverified_smart_contract(address_hash, params_with_external_libraries, "Unexpected error", nil)}
end end
end end
@ -76,7 +76,7 @@ defmodule Explorer.SmartContract.Solidity.Publisher do
"sourceFiles" => _, "sourceFiles" => _,
"compilerSettings" => _ "compilerSettings" => _
} = result_params} -> } = result_params} ->
proccess_rust_verifier_response(result_params, address_hash, true, true) process_rust_verifier_response(result_params, address_hash, true, true)
{:ok, %{abi: abi, constructor_arguments: constructor_arguments}, additional_params} -> {:ok, %{abi: abi, constructor_arguments: constructor_arguments}, additional_params} ->
params_with_constructor_arguments = params_with_constructor_arguments =
@ -102,9 +102,9 @@ defmodule Explorer.SmartContract.Solidity.Publisher do
end end
def publish_with_multi_part_files(%{"address_hash" => address_hash} = params, external_libraries \\ %{}, files) do def publish_with_multi_part_files(%{"address_hash" => address_hash} = params, external_libraries \\ %{}, files) do
params_with_external_libaries = add_external_libraries(params, external_libraries) params_with_external_libraries = add_external_libraries(params, external_libraries)
case Verifier.evaluate_authenticity_via_multi_part_files(address_hash, params_with_external_libaries, files) do case Verifier.evaluate_authenticity_via_multi_part_files(address_hash, params_with_external_libraries, files) do
{:ok, {:ok,
%{ %{
"abi" => _, "abi" => _,
@ -115,7 +115,7 @@ defmodule Explorer.SmartContract.Solidity.Publisher do
"sourceFiles" => _, "sourceFiles" => _,
"compilerSettings" => _ "compilerSettings" => _
} = result_params} -> } = result_params} ->
proccess_rust_verifier_response(result_params, address_hash, false, true) process_rust_verifier_response(result_params, address_hash, false, true)
{:error, error} -> {:error, error} ->
{:error, unverified_smart_contract(address_hash, params, error, nil, true)} {:error, unverified_smart_contract(address_hash, params, error, nil, true)}
@ -125,7 +125,7 @@ defmodule Explorer.SmartContract.Solidity.Publisher do
end end
end end
def proccess_rust_verifier_response( def process_rust_verifier_response(
%{ %{
"abi" => abi_string, "abi" => abi_string,
"compilerVersion" => compiler_version, "compilerVersion" => compiler_version,
@ -230,7 +230,7 @@ defmodule Explorer.SmartContract.Solidity.Publisher do
compiler_settings compiler_settings
end end
prepared_external_libraries = prepare_external_libraies(params["external_libraries"]) prepared_external_libraries = prepare_external_libraries(params["external_libraries"])
compiler_version = CompilerVersion.get_strict_compiler_version(:solc, params["compiler_version"]) compiler_version = CompilerVersion.get_strict_compiler_version(:solc, params["compiler_version"])
@ -256,9 +256,9 @@ defmodule Explorer.SmartContract.Solidity.Publisher do
} }
end end
defp prepare_external_libraies(nil), do: [] defp prepare_external_libraries(nil), do: []
defp prepare_external_libraies(map) do defp prepare_external_libraries(map) do
map map
|> Enum.map(fn {key, value} -> |> Enum.map(fn {key, value} ->
%{name: key, address_hash: value} %{name: key, address_hash: value}

@ -426,19 +426,19 @@ defmodule Explorer.SmartContract.Solidity.Verifier do
end end
defp check_users_constructor_args_validity(bc_bytecode, local_bytecode, bc_splitter, local_splitter, user_arguments) do defp check_users_constructor_args_validity(bc_bytecode, local_bytecode, bc_splitter, local_splitter, user_arguments) do
clear_bc_bytecode = bc_bytecode |> replace_last_occurence(user_arguments) |> replace_last_occurence(bc_splitter) clear_bc_bytecode = bc_bytecode |> replace_last_occurrence(user_arguments) |> replace_last_occurrence(bc_splitter)
clear_local_bytecode = replace_last_occurence(local_bytecode, local_splitter) clear_local_bytecode = replace_last_occurrence(local_bytecode, local_splitter)
clear_bc_bytecode == clear_local_bytecode clear_bc_bytecode == clear_local_bytecode
end end
defp replace_last_occurence(where, what) when is_binary(where) and is_binary(what) do defp replace_last_occurrence(where, what) when is_binary(where) and is_binary(what) do
where where
|> String.reverse() |> String.reverse()
|> String.replace(String.reverse(what), "", global: false) |> String.replace(String.reverse(what), "", global: false)
|> String.reverse() |> String.reverse()
end end
defp replace_last_occurence(_, _), do: nil defp replace_last_occurrence(_, _), do: nil
defp parse_constructor_and_return_check_function(abi) do defp parse_constructor_and_return_check_function(abi) do
constructor_abi = Enum.find(abi, fn el -> el["type"] == "constructor" && el["inputs"] != [] end) constructor_abi = Enum.find(abi, fn el -> el["type"] == "constructor" && el["inputs"] != [] end)
@ -513,7 +513,7 @@ defmodule Explorer.SmartContract.Solidity.Verifier do
bytecode_without_meta = bytecode_without_meta =
bytecode bytecode
|> replace_last_occurence(meta <> meta_length) |> replace_last_occurrence(meta <> meta_length)
%{ %{
"metadata_hash_with_length" => meta <> meta_length, "metadata_hash_with_length" => meta <> meta_length,

@ -1,6 +1,6 @@
defmodule Explorer.Validator.MetadataRetriever do defmodule Explorer.Validator.MetadataRetriever do
@moduledoc """ @moduledoc """
Consults the configured smart contracts to fetch the valivators' metadata Consults the configured smart contracts to fetch the validators' metadata
""" """
alias Explorer.SmartContract.Reader alias Explorer.SmartContract.Reader
@ -55,7 +55,7 @@ defmodule Explorer.Validator.MetadataRetriever do
expiration_date, expiration_date,
created_date, created_date,
_updated_date, _updated_date,
_min_treshold _min_threshold
]) do ]) do
%{ %{
name: trim_null_bytes(first_name) <> " " <> trim_null_bytes(last_name), name: trim_null_bytes(first_name) <> " " <> trim_null_bytes(last_name),

@ -18,7 +18,7 @@ defmodule Explorer.Visualize.Sol2uml do
case HTTPoison.post(url, Jason.encode!(body), headers, recv_timeout: @post_timeout) do case HTTPoison.post(url, Jason.encode!(body), headers, recv_timeout: @post_timeout) do
{:ok, %Response{body: body, status_code: 200}} -> {:ok, %Response{body: body, status_code: 200}} ->
proccess_visualizer_response(body) process_visualizer_response(body)
{:ok, %Response{body: body, status_code: status_code}} -> {:ok, %Response{body: body, status_code: status_code}} ->
Logger.error(fn -> ["Invalid status code from visualizer: #{status_code}. body: ", inspect(body)] end) Logger.error(fn -> ["Invalid status code from visualizer: #{status_code}. body: ", inspect(body)] end)
@ -40,21 +40,21 @@ defmodule Explorer.Visualize.Sol2uml do
end end
end end
def proccess_visualizer_response(body) when is_binary(body) do def process_visualizer_response(body) when is_binary(body) do
case Jason.decode(body) do case Jason.decode(body) do
{:ok, decoded} -> {:ok, decoded} ->
proccess_visualizer_response(decoded) process_visualizer_response(decoded)
_ -> _ ->
{:error, body} {:error, body}
end end
end end
def proccess_visualizer_response(%{"svg" => svg}) do def process_visualizer_response(%{"svg" => svg}) do
{:ok, svg} {:ok, svg}
end end
def proccess_visualizer_response(other), do: {:error, other} def process_visualizer_response(other), do: {:error, other}
def visualize_contracts_url, do: "#{base_api_url()}" <> "/solidity:visualize-contracts" def visualize_contracts_url, do: "#{base_api_url()}" <> "/solidity:visualize-contracts"

@ -53,7 +53,7 @@ defmodule Explorer.Account.Notify.NotifyTest do
assert wn == nil assert wn == nil
end end
test "when address apears in watchlist" do test "when address appears in watchlist" do
wa = wa =
%WatchlistAddress{address_hash: address_hash} = %WatchlistAddress{address_hash: address_hash} =
build(:account_watchlist_address) build(:account_watchlist_address)

@ -1,4 +1,4 @@
defmodule Exploer.Admin.Administrator.RoleTest do defmodule Explorer.Admin.Administrator.RoleTest do
use ExUnit.Case use ExUnit.Case
alias Explorer.Admin.Administrator.Role alias Explorer.Admin.Administrator.Role

@ -52,7 +52,7 @@ defmodule Explorer.Chain.Events.PublisherTest do
end end
describe "broadcast/1" do describe "broadcast/1" do
test "sends event whithout type of broadcast" do test "sends event without type of broadcast" do
event_type = :exchange_rate event_type = :exchange_rate
Subscriber.to(event_type) Subscriber.to(event_type)

@ -264,7 +264,7 @@ defmodule Explorer.Chain.Import.Runner.BlocksTest do
end end
# Regression test for https://github.com/poanetwork/blockscout/issues/1644 # Regression test for https://github.com/poanetwork/blockscout/issues/1644
test "discards neighbouring blocks if they aren't related to the current one because of reorg and/or import timeout", test "discards neighboring blocks if they aren't related to the current one because of reorg and/or import timeout",
%{consensus_block: %{number: block_number, hash: block_hash, miner_hash: miner_hash}, options: options} do %{consensus_block: %{number: block_number, hash: block_hash, miner_hash: miner_hash}, options: options} do
insert(:block, %{number: block_number, hash: block_hash}) insert(:block, %{number: block_number, hash: block_hash})
old_block1 = params_for(:block, miner_hash: miner_hash, parent_hash: block_hash, number: block_number + 1) old_block1 = params_for(:block, miner_hash: miner_hash, parent_hash: block_hash, number: block_number + 1)

@ -58,7 +58,7 @@ defmodule Explorer.Chain.SmartContractTest do
verify!(EthereumJSONRPC.Mox) verify!(EthereumJSONRPC.Mox)
end end
test "test get_implementation_adddress_hash/1" do test "test get_implementation_address_hash/1" do
smart_contract = insert(:smart_contract) smart_contract = insert(:smart_contract)
implementation_smart_contract = insert(:smart_contract, name: "proxy") implementation_smart_contract = insert(:smart_contract, name: "proxy")
@ -137,7 +137,7 @@ defmodule Explorer.Chain.SmartContractTest do
assert_empty_implementation(smart_contract.address_hash) assert_empty_implementation(smart_contract.address_hash)
end end
test "test get_implementation_adddress_hash/1 for twins contract" do test "test get_implementation_address_hash/1 for twins contract" do
# return nils for nil # return nils for nil
assert {nil, nil} = SmartContract.get_implementation_address_hash(nil) assert {nil, nil} = SmartContract.get_implementation_address_hash(nil)
smart_contract = insert(:smart_contract) smart_contract = insert(:smart_contract)

@ -244,7 +244,7 @@ defmodule Explorer.Chain.TransactionTest do
end end
describe "decoded_input_data/1" do describe "decoded_input_data/1" do
test "that a tranasction that is not a contract call returns a commensurate error" do test "that a transaction that is not a contract call returns a commensurate error" do
transaction = insert(:transaction) transaction = insert(:transaction)
assert Transaction.decoded_input_data(transaction) == {:error, :not_a_contract_call} assert Transaction.decoded_input_data(transaction) == {:error, :not_a_contract_call}

@ -53,7 +53,7 @@ defmodule Explorer.ChainSpec.Parity.ImporterTest do
assert {3, nil} = Importer.import_emission_rewards(@chain_spec) assert {3, nil} = Importer.import_emission_rewards(@chain_spec)
end end
test "rewrites all recored" do test "rewrites all recorded" do
old_block_rewards = %{ old_block_rewards = %{
"0x0" => "0x1bc16d674ec80000", "0x0" => "0x1bc16d674ec80000",
"0x42ae50" => "0x29a2241af62c0000", "0x42ae50" => "0x29a2241af62c0000",

@ -6119,7 +6119,7 @@ defmodule Explorer.ChainTest do
assert implementation_abi == @implementation_abi assert implementation_abi == @implementation_abi
end end
test "get_implementation_abi/1 returns empty [] abi if implmentation address is null" do test "get_implementation_abi/1 returns empty [] abi if implementation address is null" do
assert Chain.get_implementation_abi(nil) == [] assert Chain.get_implementation_abi(nil) == []
end end

@ -121,7 +121,7 @@ defmodule Explorer.GraphQLTest do
end end
end end
describe "transcation_to_internal_transactions_query/1" do describe "transaction_to_internal_transactions_query/1" do
test "with transaction with one internal transaction" do test "with transaction with one internal transaction" do
transaction1 = insert(:transaction) |> with_block() transaction1 = insert(:transaction) |> with_block()
transaction2 = insert(:transaction) |> with_block() transaction2 = insert(:transaction) |> with_block()

@ -16,7 +16,7 @@ defmodule Explorer.SmartContract.Solidity.CodeCompilerTest do
setup do setup do
{:ok, {:ok,
contract_code_info: Factory.contract_code_info(), contract_code_info: Factory.contract_code_info(),
contract_code_info_modern_compilator: Factory.contract_code_info_modern_compilator()} contract_code_info_modern_compiler: Factory.contract_code_info_modern_compiler()}
end end
test "compiles the latest solidity version", %{contract_code_info: contract_code_info} do test "compiles the latest solidity version", %{contract_code_info: contract_code_info} do
@ -38,15 +38,15 @@ defmodule Explorer.SmartContract.Solidity.CodeCompilerTest do
end end
test "compiles a optimized smart contract", %{ test "compiles a optimized smart contract", %{
contract_code_info_modern_compilator: contract_code_info_modern_compilator contract_code_info_modern_compiler: contract_code_info_modern_compiler
} do } do
optimize = true optimize = true
response = response =
CodeCompiler.run( CodeCompiler.run(
name: contract_code_info_modern_compilator.name, name: contract_code_info_modern_compiler.name,
compiler_version: contract_code_info_modern_compilator.version, compiler_version: contract_code_info_modern_compiler.version,
code: contract_code_info_modern_compilator.source_code, code: contract_code_info_modern_compiler.source_code,
optimize: optimize, optimize: optimize,
evm_version: "byzantium" evm_version: "byzantium"
) )
@ -60,15 +60,15 @@ defmodule Explorer.SmartContract.Solidity.CodeCompilerTest do
end end
test "compiles smart contract with default evm version", %{ test "compiles smart contract with default evm version", %{
contract_code_info_modern_compilator: contract_code_info_modern_compilator contract_code_info_modern_compiler: contract_code_info_modern_compiler
} do } do
optimize = true optimize = true
response = response =
CodeCompiler.run( CodeCompiler.run(
name: contract_code_info_modern_compilator.name, name: contract_code_info_modern_compiler.name,
compiler_version: contract_code_info_modern_compilator.version, compiler_version: contract_code_info_modern_compiler.version,
code: contract_code_info_modern_compilator.source_code, code: contract_code_info_modern_compiler.source_code,
optimize: optimize, optimize: optimize,
evm_version: "default" evm_version: "default"
) )

@ -13,7 +13,7 @@ defmodule Explorer.SmartContract.Solidity.PublisherTest do
describe "publish/2" do describe "publish/2" do
test "with valid data creates a smart_contract" do test "with valid data creates a smart_contract" do
contract_code_info = Factory.contract_code_info_modern_compilator() contract_code_info = Factory.contract_code_info_modern_compiler()
contract_address = insert(:contract_address, contract_code: contract_code_info.bytecode) contract_address = insert(:contract_address, contract_code: contract_code_info.bytecode)
@ -76,7 +76,7 @@ defmodule Explorer.SmartContract.Solidity.PublisherTest do
end end
test "corresponding contract_methods are created for the abi" do test "corresponding contract_methods are created for the abi" do
contract_code_info = Factory.contract_code_info_modern_compilator() contract_code_info = Factory.contract_code_info_modern_compiler()
contract_address = insert(:contract_address, contract_code: contract_code_info.bytecode) contract_address = insert(:contract_address, contract_code: contract_code_info.bytecode)

@ -597,12 +597,12 @@ defmodule Explorer.SmartContract.Solidity.VerifierTest do
constructor_arguments = "000000000000000000000000000000000000000000000000000000000000000a" constructor_arguments = "000000000000000000000000000000000000000000000000000000000000000a"
contract_address = insert(:contract_address, contract_code: bytecode_0_5_10) contract_address = insert(:contract_address, contract_code: bytecode_0_5_10)
bytecode_construtor_arguments = "#{bytecode_0_5_10}#{constructor_arguments}" bytecode_constructor_arguments = "#{bytecode_0_5_10}#{constructor_arguments}"
:transaction :transaction
|> insert( |> insert(
created_contract_address_hash: contract_address.hash, created_contract_address_hash: contract_address.hash,
input: bytecode_construtor_arguments input: bytecode_constructor_arguments
) )
|> with_block(status: :ok) |> with_block(status: :ok)
@ -625,12 +625,12 @@ defmodule Explorer.SmartContract.Solidity.VerifierTest do
constructor_arguments = "000000000000000000000000000000000000000000000000000000000000000a" constructor_arguments = "000000000000000000000000000000000000000000000000000000000000000a"
contract_address = insert(:contract_address, contract_code: bytecode_0_5_10) contract_address = insert(:contract_address, contract_code: bytecode_0_5_10)
bytecode_construtor_arguments = "#{bytecode_0_5_10}#{constructor_arguments}" bytecode_constructor_arguments = "#{bytecode_0_5_10}#{constructor_arguments}"
:transaction :transaction
|> insert( |> insert(
created_contract_address_hash: contract_address.hash, created_contract_address_hash: contract_address.hash,
input: bytecode_construtor_arguments input: bytecode_constructor_arguments
) )
|> with_block(status: :ok) |> with_block(status: :ok)
@ -655,12 +655,12 @@ defmodule Explorer.SmartContract.Solidity.VerifierTest do
constructor_arguments = "000000000000000000000000000000000000000000000000000000000000000a" constructor_arguments = "000000000000000000000000000000000000000000000000000000000000000a"
contract_address = insert(:contract_address, contract_code: bytecode_v0_4_24_nightly_2018_4_26_commit_ef2111a2) contract_address = insert(:contract_address, contract_code: bytecode_v0_4_24_nightly_2018_4_26_commit_ef2111a2)
bytecode_construtor_arguments = "#{bytecode_v0_4_24_nightly_2018_4_26_commit_ef2111a2}#{constructor_arguments}" bytecode_constructor_arguments = "#{bytecode_v0_4_24_nightly_2018_4_26_commit_ef2111a2}#{constructor_arguments}"
:transaction :transaction
|> insert( |> insert(
created_contract_address_hash: contract_address.hash, created_contract_address_hash: contract_address.hash,
input: bytecode_construtor_arguments input: bytecode_constructor_arguments
) )
|> with_block(status: :ok) |> with_block(status: :ok)
@ -683,12 +683,12 @@ defmodule Explorer.SmartContract.Solidity.VerifierTest do
constructor_arguments = "000000000000000000000000000000000000000000000000000000000000000a" constructor_arguments = "000000000000000000000000000000000000000000000000000000000000000a"
contract_address = insert(:contract_address, contract_code: bytecode_0_5_10_nightly_2019_6_4_commit_95e6b2e4) contract_address = insert(:contract_address, contract_code: bytecode_0_5_10_nightly_2019_6_4_commit_95e6b2e4)
bytecode_construtor_arguments = "#{bytecode_0_5_10_nightly_2019_6_4_commit_95e6b2e4}#{constructor_arguments}" bytecode_constructor_arguments = "#{bytecode_0_5_10_nightly_2019_6_4_commit_95e6b2e4}#{constructor_arguments}"
:transaction :transaction
|> insert( |> insert(
created_contract_address_hash: contract_address.hash, created_contract_address_hash: contract_address.hash,
input: bytecode_construtor_arguments input: bytecode_constructor_arguments
) )
|> with_block(status: :ok) |> with_block(status: :ok)
@ -711,12 +711,12 @@ defmodule Explorer.SmartContract.Solidity.VerifierTest do
constructor_arguments = "000000000000000000000000000000000000000000000000000000000000000a" constructor_arguments = "000000000000000000000000000000000000000000000000000000000000000a"
contract_address = insert(:contract_address, contract_code: bytecode_0_5_11_nightly_2019_6_25_commit_1cc84753) contract_address = insert(:contract_address, contract_code: bytecode_0_5_11_nightly_2019_6_25_commit_1cc84753)
bytecode_construtor_arguments = "#{bytecode_0_5_11_nightly_2019_6_25_commit_1cc84753}#{constructor_arguments}" bytecode_constructor_arguments = "#{bytecode_0_5_11_nightly_2019_6_25_commit_1cc84753}#{constructor_arguments}"
:transaction :transaction
|> insert( |> insert(
created_contract_address_hash: contract_address.hash, created_contract_address_hash: contract_address.hash,
input: bytecode_construtor_arguments input: bytecode_constructor_arguments
) )
|> with_block(status: :ok) |> with_block(status: :ok)
@ -739,12 +739,12 @@ defmodule Explorer.SmartContract.Solidity.VerifierTest do
constructor_arguments = "000000000000000000000000000000000000000000000000000000000000000a" constructor_arguments = "000000000000000000000000000000000000000000000000000000000000000a"
contract_address = insert(:contract_address, contract_code: bytecode_0_5_14_nightly_2019_12_10_commit_45aa7a88) contract_address = insert(:contract_address, contract_code: bytecode_0_5_14_nightly_2019_12_10_commit_45aa7a88)
bytecode_construtor_arguments = "#{bytecode_0_5_14_nightly_2019_12_10_commit_45aa7a88}#{constructor_arguments}" bytecode_constructor_arguments = "#{bytecode_0_5_14_nightly_2019_12_10_commit_45aa7a88}#{constructor_arguments}"
:transaction :transaction
|> insert( |> insert(
created_contract_address_hash: contract_address.hash, created_contract_address_hash: contract_address.hash,
input: bytecode_construtor_arguments input: bytecode_constructor_arguments
) )
|> with_block(status: :ok) |> with_block(status: :ok)
@ -767,12 +767,12 @@ defmodule Explorer.SmartContract.Solidity.VerifierTest do
constructor_arguments = "000000000000000000000000000000000000000000000000000000000000000a" constructor_arguments = "000000000000000000000000000000000000000000000000000000000000000a"
contract_address = insert(:contract_address, contract_code: bytecode_0_6_1_nightly_2020_1_2_commit_d082b9b8) contract_address = insert(:contract_address, contract_code: bytecode_0_6_1_nightly_2020_1_2_commit_d082b9b8)
bytecode_construtor_arguments = "#{bytecode_0_6_1_nightly_2020_1_2_commit_d082b9b8}#{constructor_arguments}" bytecode_constructor_arguments = "#{bytecode_0_6_1_nightly_2020_1_2_commit_d082b9b8}#{constructor_arguments}"
:transaction :transaction
|> insert( |> insert(
created_contract_address_hash: contract_address.hash, created_contract_address_hash: contract_address.hash,
input: bytecode_construtor_arguments input: bytecode_constructor_arguments
) )
|> with_block(status: :ok) |> with_block(status: :ok)
@ -795,12 +795,12 @@ defmodule Explorer.SmartContract.Solidity.VerifierTest do
constructor_arguments = "000000000000000000000000000000000000000000000000000000000000000a" constructor_arguments = "000000000000000000000000000000000000000000000000000000000000000a"
contract_address = insert(:contract_address, contract_code: bytecode_0_5_11_nightly_2019_6_25_commit_1cc84753) contract_address = insert(:contract_address, contract_code: bytecode_0_5_11_nightly_2019_6_25_commit_1cc84753)
bytecode_construtor_arguments = "#{bytecode_0_5_11_nightly_2019_6_25_commit_1cc84753}#{constructor_arguments}" bytecode_constructor_arguments = "#{bytecode_0_5_11_nightly_2019_6_25_commit_1cc84753}#{constructor_arguments}"
:transaction :transaction
|> insert( |> insert(
created_contract_address_hash: contract_address.hash, created_contract_address_hash: contract_address.hash,
input: bytecode_construtor_arguments input: bytecode_constructor_arguments
) )
|> with_block(status: :ok) |> with_block(status: :ok)

@ -267,7 +267,7 @@ defmodule Explorer.Factory do
} }
end end
def contract_code_info_modern_compilator do def contract_code_info_modern_compiler do
%{ %{
bytecode: bytecode:
"0x608060405234801561001057600080fd5b50610150806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806360fe47b11461003b5780636d4ce63c14610057575b600080fd5b610055600480360381019061005091906100c3565b610075565b005b61005f61007f565b60405161006c91906100ff565b60405180910390f35b8060008190555050565b60008054905090565b600080fd5b6000819050919050565b6100a08161008d565b81146100ab57600080fd5b50565b6000813590506100bd81610097565b92915050565b6000602082840312156100d9576100d8610088565b5b60006100e7848285016100ae565b91505092915050565b6100f98161008d565b82525050565b600060208201905061011460008301846100f0565b9291505056fea2646970667358221220d5d429d16f620053da9907372b66303e007b04bfd112159cff82cb67ff40da4264736f6c634300080a0033", "0x608060405234801561001057600080fd5b50610150806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806360fe47b11461003b5780636d4ce63c14610057575b600080fd5b610055600480360381019061005091906100c3565b610075565b005b61005f61007f565b60405161006c91906100ff565b60405180910390f35b8060008190555050565b60008054905090565b600080fd5b6000819050919050565b6100a08161008d565b81146100ab57600080fd5b50565b6000813590506100bd81610097565b92915050565b6000602082840312156100d9576100d8610088565b5b60006100e7848285016100ae565b91505092915050565b6100f98161008d565b82525050565b600060208201905061011460008301846100f0565b9291505056fea2646970667358221220d5d429d16f620053da9907372b66303e007b04bfd112159cff82cb67ff40da4264736f6c634300080a0033",

@ -22,7 +22,7 @@ Some data has to be extracted from already fetched data, and there're several tr
- `token_transfers`: parses logs to extract token transfers - `token_transfers`: parses logs to extract token transfers
- `mint_transfers`: parses logs to extract token mint transfers - `mint_transfers`: parses logs to extract token mint transfers
- `transaction_actions`: parses logs to extract transaction actions - `transaction_actions`: parses logs to extract transaction actions
- `address_token_balances`: creates token balance entities for futher fetching, based on detected token transfers - `address_token_balances`: creates token balance entities for further fetching, based on detected token transfers
- `blocks`: extracts block signer hash from additional data for Clique chains - `blocks`: extracts block signer hash from additional data for Clique chains
### Root fetchers ### Root fetchers

@ -4,7 +4,7 @@ defmodule Indexer.Fetcher.CoinBalanceOnDemand do
If we have an unfetched coin balance for that address, it will be synchronously fetched. If we have an unfetched coin balance for that address, it will be synchronously fetched.
If not we will fetch the coin balance and created a fetched coin balance. If not we will fetch the coin balance and created a fetched coin balance.
If we have a fetched coin balance, but it is over 100 blocks old, we will fetch and create a fetched coin baalnce. If we have a fetched coin balance, but it is over 100 blocks old, we will fetch and create a fetched coin balance.
""" """
use GenServer use GenServer
@ -233,8 +233,8 @@ defmodule Indexer.Fetcher.CoinBalanceOnDemand do
defp stale_balance_window(block_number) do defp stale_balance_window(block_number) do
case AverageBlockTime.average_block_time() do case AverageBlockTime.average_block_time() do
{:error, :disabled} -> {:error, :disabled} ->
fallback_treshold_in_blocks = Application.get_env(:indexer, __MODULE__)[:fallback_treshold_in_blocks] fallback_threshold_in_blocks = Application.get_env(:indexer, __MODULE__)[:fallback_threshold_in_blocks]
block_number - fallback_treshold_in_blocks block_number - fallback_threshold_in_blocks
duration -> duration ->
average_block_time = average_block_time =

@ -231,7 +231,7 @@ defmodule Indexer.Fetcher.InternalTransaction do
case imports do case imports do
{:ok, imported} -> {:ok, imported} ->
Accounts.drop(imported[:addreses]) Accounts.drop(imported[:addresses])
Blocks.drop_nonconsensus(imported[:remove_consensus_of_missing_transactions_blocks]) Blocks.drop_nonconsensus(imported[:remove_consensus_of_missing_transactions_blocks])
async_import_coin_balances(imported, %{ async_import_coin_balances(imported, %{

@ -93,8 +93,8 @@ defmodule Indexer.Fetcher.TokenBalanceOnDemand do
defp stale_balance_window(block_number) do defp stale_balance_window(block_number) do
case AverageBlockTime.average_block_time() do case AverageBlockTime.average_block_time() do
{:error, :disabled} -> {:error, :disabled} ->
fallback_treshold_in_blocks = Application.get_env(:indexer, __MODULE__)[:fallback_treshold_in_blocks] fallback_threshold_in_blocks = Application.get_env(:indexer, __MODULE__)[:fallback_threshold_in_blocks]
block_number - fallback_treshold_in_blocks block_number - fallback_threshold_in_blocks
duration -> duration ->
average_block_time = average_block_time =

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save