Merge branch 'master' of github.com:poanetwork/blockscout

pull/2655/head
Yegor San 5 years ago
commit a85aada03b
  1. 11
      CHANGELOG.md
  2. 1
      apps/block_scout_web/assets/css/_images-preload.scss
  3. 3
      apps/block_scout_web/assets/css/components/_network-selector.scss
  4. 236
      apps/block_scout_web/assets/package-lock.json
  5. 4
      apps/block_scout_web/assets/package.json
  6. BIN
      apps/block_scout_web/assets/static/images/network-selector-icons/lukso-l14-testnet.png
  7. 5
      apps/block_scout_web/lib/block_scout_web/etherscan.ex
  8. 6
      apps/block_scout_web/lib/block_scout_web/templates/layout/_topnav.html.eex
  9. 3
      apps/block_scout_web/lib/block_scout_web/views/api/rpc/address_view.ex
  10. 2
      apps/block_scout_web/mix.exs
  11. 35
      apps/block_scout_web/test/block_scout_web/controllers/api/rpc/address_controller_test.exs
  12. 1
      apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/parity/fetched_beneficiaries.ex
  13. 116
      apps/ethereum_jsonrpc/test/ethereum_jsonrpc/rolling_window_test.exs
  14. 2
      apps/explorer/config/config.exs
  15. 7
      apps/explorer/lib/explorer/chain.ex
  16. 1
      apps/explorer/lib/explorer/chain_spec/genesis_data.ex
  17. 12
      apps/explorer/lib/explorer/etherscan.ex
  18. 8
      apps/explorer/lib/explorer/smart_contract/verifier.ex
  19. 10
      apps/explorer/lib/explorer/smart_contract/verifier/constructor_arguments.ex
  20. 26
      apps/explorer/test/explorer/chain_test.exs
  21. 97
      apps/explorer/test/explorer/etherscan_test.exs
  22. 27
      apps/explorer/test/explorer/smart_contract/verifier_test.exs
  23. 7
      apps/explorer/test/support/fixture/smart_contract/solidity_5.11_new_whisper_metadata.json
  24. 4
      apps/indexer/lib/indexer/block/fetcher.ex
  25. 98
      docs/env-variables.md
  26. 2
      mix.lock

@ -1,11 +1,17 @@
## Current ## Current
### Features ### Features
- [#2596](https://github.com/poanetwork/blockscout/pull/2596) - support AuRa's empty step reward type
- [#2561](https://github.com/poanetwork/blockscout/pull/2561) - Add token's type to the response of tokenlist method - [#2561](https://github.com/poanetwork/blockscout/pull/2561) - Add token's type to the response of tokenlist method
- [#2499](https://github.com/poanetwork/blockscout/pull/2499) - import emission reward ranges - [#2499](https://github.com/poanetwork/blockscout/pull/2499) - import emission reward ranges
- [#2497](https://github.com/poanetwork/blockscout/pull/2497) - Add generic Ordered Cache behaviour and implementation - [#2497](https://github.com/poanetwork/blockscout/pull/2497) - Add generic Ordered Cache behaviour and implementation
### Fixes ### Fixes
- [#2626](https://github.com/poanetwork/blockscout/pull/2626) - Fixing 2 Mobile UI Issues
- [#2623](https://github.com/poanetwork/blockscout/pull/2623) - fix a blinking test
- [#2616](https://github.com/poanetwork/blockscout/pull/2616) - deduplicate coin history records by delta
- [#2613](https://github.com/poanetwork/blockscout/pull/2613) - fix getminedblocks rpc endpoint
- [#2592](https://github.com/poanetwork/blockscout/pull/2592) - process new metadata format for whisper
- [#2572](https://github.com/poanetwork/blockscout/pull/2572) - Ease non-critical css - [#2572](https://github.com/poanetwork/blockscout/pull/2572) - Ease non-critical css
- [#2570](https://github.com/poanetwork/blockscout/pull/2570) - Network icons preload - [#2570](https://github.com/poanetwork/blockscout/pull/2570) - Network icons preload
- [#2569](https://github.com/poanetwork/blockscout/pull/2569) - do not fetch emission rewards for transactions csv exporter - [#2569](https://github.com/poanetwork/blockscout/pull/2569) - do not fetch emission rewards for transactions csv exporter
@ -15,7 +21,12 @@
- [#2538](https://github.com/poanetwork/blockscout/pull/2538) - fetch the last not empty coin balance records - [#2538](https://github.com/poanetwork/blockscout/pull/2538) - fetch the last not empty coin balance records
### Chore ### Chore
- [#2634](https://github.com/poanetwork/blockscout/pull/2634) - add Lukso to networks dropdown
- [#2611](https://github.com/poanetwork/blockscout/pull/2611) - fix js dependency vulnerabilities
- [#2617](https://github.com/poanetwork/blockscout/pull/2617) - skip cache update if there are no blocks inserted
- [#2594](https://github.com/poanetwork/blockscout/pull/2594) - do not start genesis data fetching periodically
- [#2590](https://github.com/poanetwork/blockscout/pull/2590) - restore backward compatablity with old releases - [#2590](https://github.com/poanetwork/blockscout/pull/2590) - restore backward compatablity with old releases
- [#2577](https://github.com/poanetwork/blockscout/pull/2577) - Need recompile column in the env vars table
- [#2574](https://github.com/poanetwork/blockscout/pull/2574) - limit request body in json rpc error - [#2574](https://github.com/poanetwork/blockscout/pull/2574) - limit request body in json rpc error
- [#2566](https://github.com/poanetwork/blockscout/pull/2566) - upgrade absinthe phoenix - [#2566](https://github.com/poanetwork/blockscout/pull/2566) - upgrade absinthe phoenix

@ -12,4 +12,5 @@ body:after {
url(/images/network-selector-icons/rsk-mainnet.png) url(/images/network-selector-icons/rsk-mainnet.png)
url(/images/network-selector-icons/ropsten-testnet.png) url(/images/network-selector-icons/ropsten-testnet.png)
url(/images/network-selector-icons/xdai-chain.png) url(/images/network-selector-icons/xdai-chain.png)
url(/images/network-selector-icons/lukso-l14-testnet.png)
}; };

@ -277,6 +277,9 @@ $network-selector-item-icon-dimensions: 30px !default;
&-xdai-chain { &-xdai-chain {
background-image: url(/images/network-selector-icons/xdai-chain.png) background-image: url(/images/network-selector-icons/xdai-chain.png)
} }
&-lukso-l14-testnet {
background-image: url(/images/network-selector-icons/lukso-l14-testnet.png)
}
} }
.network-selector-item-title { .network-selector-item-title {

@ -2678,8 +2678,7 @@
"esprima": { "esprima": {
"version": "4.0.1", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
"dev": true
}, },
"is-svg": { "is-svg": {
"version": "3.0.0", "version": "3.0.0",
@ -2690,16 +2689,6 @@
"html-comment-regex": "^1.1.0" "html-comment-regex": "^1.1.0"
} }
}, },
"js-yaml": {
"version": "3.13.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
"integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
"dev": true,
"requires": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
}
},
"mdn-data": { "mdn-data": {
"version": "1.1.4", "version": "1.1.4",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-1.1.4.tgz", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-1.1.4.tgz",
@ -3638,8 +3627,7 @@
"esprima": { "esprima": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
"integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw=="
"dev": true
}, },
"globals": { "globals": {
"version": "11.7.0", "version": "11.7.0",
@ -3647,16 +3635,6 @@
"integrity": "sha512-K8BNSPySfeShBQXsahYB/AbbWruVOTyVpgoIDnl8odPpeSfP2J5QO2oLFFdl2j7GfDCtZj2bMKar2T49itTPCg==", "integrity": "sha512-K8BNSPySfeShBQXsahYB/AbbWruVOTyVpgoIDnl8odPpeSfP2J5QO2oLFFdl2j7GfDCtZj2bMKar2T49itTPCg==",
"dev": true "dev": true
}, },
"js-yaml": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz",
"integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==",
"dev": true,
"requires": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
}
},
"strip-ansi": { "strip-ansi": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
@ -3812,12 +3790,6 @@
"acorn-jsx": "^3.0.0" "acorn-jsx": "^3.0.0"
} }
}, },
"esprima": {
"version": "2.7.3",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
"integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
"dev": true
},
"esquery": { "esquery": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz",
@ -3980,9 +3952,9 @@
} }
}, },
"extend": { "extend": {
"version": "3.0.1", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
"integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
"dev": true "dev": true
}, },
"extend-shallow": { "extend-shallow": {
@ -4293,6 +4265,16 @@
"readable-stream": "^2.0.0" "readable-stream": "^2.0.0"
} }
}, },
"fs-minipass": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.6.tgz",
"integrity": "sha512-crhvyXcMejjv3Z5d2Fa9sf5xLYVCF5O1c71QxbVnbLsmYMBEvDAftewesN/HhY03YRoA7zOMxjNGrF5svGaaeQ==",
"dev": true,
"optional": true,
"requires": {
"minipass": "^2.2.1"
}
},
"fs-write-stream-atomic": { "fs-write-stream-atomic": {
"version": "1.0.10", "version": "1.0.10",
"resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
@ -4375,9 +4357,7 @@
"chownr": { "chownr": {
"version": "1.0.1", "version": "1.0.1",
"resolved": false, "resolved": false,
"integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=", "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE="
"dev": true,
"optional": true
}, },
"code-point-at": { "code-point-at": {
"version": "1.1.0", "version": "1.1.0",
@ -4442,8 +4422,6 @@
"version": "1.2.5", "version": "1.2.5",
"resolved": false, "resolved": false,
"integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==",
"dev": true,
"optional": true,
"requires": { "requires": {
"minipass": "^2.2.1" "minipass": "^2.2.1"
} }
@ -4577,7 +4555,6 @@
"version": "2.2.4", "version": "2.2.4",
"resolved": false, "resolved": false,
"integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==", "integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==",
"dev": true,
"optional": true, "optional": true,
"requires": { "requires": {
"safe-buffer": "^5.1.1", "safe-buffer": "^5.1.1",
@ -4588,8 +4565,6 @@
"version": "1.1.0", "version": "1.1.0",
"resolved": false, "resolved": false,
"integrity": "sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA==", "integrity": "sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA==",
"dev": true,
"optional": true,
"requires": { "requires": {
"minipass": "^2.2.1" "minipass": "^2.2.1"
} }
@ -4799,7 +4774,6 @@
"version": "5.1.1", "version": "5.1.1",
"resolved": false, "resolved": false,
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
"dev": true,
"optional": true "optional": true
}, },
"safer-buffer": { "safer-buffer": {
@ -4876,22 +4850,6 @@
"dev": true, "dev": true,
"optional": true "optional": true
}, },
"tar": {
"version": "4.4.1",
"resolved": false,
"integrity": "sha512-O+v1r9yN4tOsvl90p5HAP4AEqbYhx4036AGMm075fH9F8Qwi3oJ+v4u50FkT/KkvywNGtwkk0zRI+8eYm1X/xg==",
"dev": true,
"optional": true,
"requires": {
"chownr": "^1.0.1",
"fs-minipass": "^1.2.5",
"minipass": "^2.2.4",
"minizlib": "^1.1.0",
"mkdirp": "^0.5.0",
"safe-buffer": "^5.1.1",
"yallist": "^3.0.2"
}
},
"util-deprecate": { "util-deprecate": {
"version": "1.0.2", "version": "1.0.2",
"resolved": false, "resolved": false,
@ -4920,15 +4878,14 @@
"version": "3.0.2", "version": "3.0.2",
"resolved": false, "resolved": false,
"integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=", "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=",
"dev": true,
"optional": true "optional": true
} }
} }
}, },
"fstream": { "fstream": {
"version": "1.0.11", "version": "1.0.12",
"resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
"integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
"dev": true, "dev": true,
"requires": { "requires": {
"graceful-fs": "^4.1.2", "graceful-fs": "^4.1.2",
@ -5158,15 +5115,23 @@
"dev": true "dev": true
}, },
"handlebars": { "handlebars": {
"version": "4.0.12", "version": "4.1.2",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.12.tgz", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.2.tgz",
"integrity": "sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA==", "integrity": "sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==",
"dev": true, "dev": true,
"requires": { "requires": {
"async": "^2.5.0", "neo-async": "^2.6.0",
"optimist": "^0.6.1", "optimist": "^0.6.1",
"source-map": "^0.6.1", "source-map": "^0.6.1",
"uglify-js": "^3.1.4" "uglify-js": "^3.1.4"
},
"dependencies": {
"neo-async": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz",
"integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==",
"dev": true
}
} }
}, },
"har-schema": { "har-schema": {
@ -6024,7 +5989,7 @@
}, },
"callsites": { "callsites": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "http://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
"integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=",
"dev": true "dev": true
}, },
@ -6226,7 +6191,7 @@
}, },
"jest-get-type": { "jest-get-type": {
"version": "22.4.3", "version": "22.4.3",
"resolved": "http://registry.npmjs.org/jest-get-type/-/jest-get-type-22.4.3.tgz", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-22.4.3.tgz",
"integrity": "sha512-/jsz0Y+V29w1chdXVygEKSz2nBoHoYqNShPe+QgxSNjAuP1i8+k4LbQNrfoliKej0P45sivkSCh7yiD6ubHS3w==", "integrity": "sha512-/jsz0Y+V29w1chdXVygEKSz2nBoHoYqNShPe+QgxSNjAuP1i8+k4LbQNrfoliKej0P45sivkSCh7yiD6ubHS3w==",
"dev": true "dev": true
}, },
@ -6758,9 +6723,9 @@
} }
}, },
"jquery": { "jquery": {
"version": "3.3.1", "version": "3.4.0",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.3.1.tgz", "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.0.tgz",
"integrity": "sha512-Ubldcmxp5np52/ENotGxlLe6aGMvmF4R8S6tZjsP6Knsaxd/xp3Zrh50cG93lR6nPXyUFwzN3ZSOQI0wRJNdGg==" "integrity": "sha512-ggRCXln9zEqv6OqAGXFEcshF5dSBvCkzj6Gm2gzuR5fWawaX8t7cxKVkkygKODrDAzKdoYw3l/e3pm3vlT4IbQ=="
}, },
"js-base64": { "js-base64": {
"version": "2.4.5", "version": "2.4.5",
@ -6774,13 +6739,21 @@
"integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls="
}, },
"js-yaml": { "js-yaml": {
"version": "3.7.0", "version": "3.13.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.7.0.tgz", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
"integrity": "sha1-XJZ93YN6m/3KXy3oQlOr6KHAO4A=", "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
"dev": true, "dev": true,
"requires": { "requires": {
"argparse": "^1.0.7", "argparse": "^1.0.7",
"esprima": "^2.6.0" "esprima": "^4.0.0"
},
"dependencies": {
"esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
"dev": true
}
} }
}, },
"jsbn": { "jsbn": {
@ -6988,9 +6961,9 @@
} }
}, },
"lodash": { "lodash": {
"version": "4.17.11", "version": "4.17.13",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.13.tgz",
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" "integrity": "sha512-vm3/XWXfWtRua0FkUyEHBZy8kCPjErNBT9fJx8Zvs+U6zjqPbTUOpkaoum3O5uiA8sm+yNMHXfYkTUHFoMxFNA=="
}, },
"lodash.assign": { "lodash.assign": {
"version": "4.2.0", "version": "4.2.0",
@ -7017,9 +6990,9 @@
"dev": true "dev": true
}, },
"lodash.mergewith": { "lodash.mergewith": {
"version": "4.6.1", "version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz", "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
"integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==", "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==",
"dev": true "dev": true
}, },
"lodash.sortby": { "lodash.sortby": {
@ -7422,6 +7395,36 @@
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
"dev": true "dev": true
}, },
"minipass": {
"version": "2.3.5",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz",
"integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==",
"dev": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
},
"dependencies": {
"yallist": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
"integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==",
"dev": true,
"optional": true
}
}
},
"minizlib": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz",
"integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==",
"dev": true,
"optional": true,
"requires": {
"minipass": "^2.2.1"
}
},
"mississippi": { "mississippi": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/mississippi/-/mississippi-2.0.0.tgz", "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-2.0.0.tgz",
@ -7608,6 +7611,31 @@
"resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
"integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
"dev": true "dev": true
},
"tar": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz",
"integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==",
"dev": true,
"requires": {
"block-stream": "*",
"fstream": "^1.0.12",
"inherits": "2"
},
"dependencies": {
"fstream": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
"integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
"dev": true,
"requires": {
"graceful-fs": "^4.1.2",
"inherits": "~2.0.0",
"mkdirp": ">=0.5 0",
"rimraf": "2"
}
}
}
} }
} }
}, },
@ -8026,18 +8054,7 @@
"esprima": { "esprima": {
"version": "4.0.1", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
"dev": true
},
"js-yaml": {
"version": "3.13.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
"integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
"dev": true,
"requires": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
}
}, },
"parse-json": { "parse-json": {
"version": "4.0.0", "version": "4.0.0",
@ -10720,14 +10737,35 @@
"dev": true "dev": true
}, },
"tar": { "tar": {
"version": "2.2.1", "version": "4.4.10",
"resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz",
"integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", "integrity": "sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA==",
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"block-stream": "*", "chownr": "^1.1.1",
"fstream": "^1.0.2", "fs-minipass": "^1.2.5",
"inherits": "2" "minipass": "^2.3.5",
"minizlib": "^1.2.1",
"mkdirp": "^0.5.0",
"safe-buffer": "^5.1.2",
"yallist": "^3.0.3"
},
"dependencies": {
"chownr": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz",
"integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==",
"dev": true,
"optional": true
},
"yallist": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
"integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==",
"dev": true,
"optional": true
}
} }
}, },
"terser": { "terser": {

@ -29,8 +29,8 @@
"highlight.js": "^9.13.1", "highlight.js": "^9.13.1",
"highlightjs-solidity": "^1.0.6", "highlightjs-solidity": "^1.0.6",
"humps": "^2.0.1", "humps": "^2.0.1",
"jquery": "^3.3.1", "jquery": "^3.4.0",
"lodash": "^4.17.11", "lodash": "^4.17.13",
"moment": "^2.22.1", "moment": "^2.22.1",
"nanomorph": "^5.1.3", "nanomorph": "^5.1.3",
"numeral": "^2.0.6", "numeral": "^2.0.6",

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

@ -713,11 +713,6 @@ defmodule BlockScoutWeb.Etherscan do
type: "timestamp", type: "timestamp",
definition: "When the block was collated.", definition: "When the block was collated.",
example: ~s("1480072029") example: ~s("1480072029")
},
blockReward: %{
type: "block reward",
definition: "The reward given to the miner of a block.",
example: ~s("5003251945421042780")
} }
} }
} }

@ -99,7 +99,7 @@
</div> </div>
</li> </li>
<% end %> <% end %>
<li class="nav-item dropdown nav-item-networks"> <li class="nav-item dropdown">
<a class="nav-link topnav-nav-link active-icon <%= if dropdown_nets() != [], do: "dropdown-toggle js-show-network-selector" %>" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <a class="nav-link topnav-nav-link active-icon <%= if dropdown_nets() != [], do: "dropdown-toggle js-show-network-selector" %>" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="nav-link-icon"> <span class="nav-link-icon">
<%= render BlockScoutWeb.IconsView, "_active_icon.html" %> <%= render BlockScoutWeb.IconsView, "_active_icon.html" %>
@ -116,7 +116,7 @@
</button> </button>
<!-- Search navbar --> <!-- Search navbar -->
<%= if Application.get_env(:block_scout_web, BlockScoutWeb.WebRouter)[:enabled] do %> <%= if Application.get_env(:block_scout_web, BlockScoutWeb.WebRouter)[:enabled] do %>
<div class="search-form d-lg-flex d-inline-block" style="background-color: #22223a"> <div class="search-form d-lg-flex d-inline-block">
<%= form_for @conn, chain_path(@conn, :search), [class: "form-inline my-2 my-lg-0", method: :get, enforce_utf8: false], fn f -> %> <%= form_for @conn, chain_path(@conn, :search), [class: "form-inline my-2 my-lg-0", method: :get, enforce_utf8: false], fn f -> %>
<div class="input-group" title='<%= gettext("Search by address, token symbol name, transaction hash, or block number") %>'> <div class="input-group" title='<%= gettext("Search by address, token symbol name, transaction hash, or block number") %>'>
<%= awesomplete(f, :q, <%= awesomplete(f, :q,
@ -160,4 +160,4 @@
var modeChanger = document.getElementById("dark-mode-changer"); var modeChanger = document.getElementById("dark-mode-changer");
modeChanger.className += " " + "dark-mode-changer--dark"; modeChanger.className += " " + "dark-mode-changer--dark";
} }
</script> </script>

@ -157,8 +157,7 @@ defmodule BlockScoutWeb.API.RPC.AddressView do
defp prepare_block(block) do defp prepare_block(block) do
%{ %{
"blockNumber" => to_string(block.number), "blockNumber" => to_string(block.number),
"timeStamp" => to_string(block.timestamp), "timeStamp" => to_string(block.timestamp)
"blockReward" => to_string(block.reward.value)
} }
end end

@ -99,7 +99,7 @@ defmodule BlockScoutWeb.Mixfile do
{:logger_file_backend, "~> 0.0.10"}, {:logger_file_backend, "~> 0.0.10"},
{:math, "~> 0.3.0"}, {:math, "~> 0.3.0"},
{:mock, "~> 0.3.0", only: [:test], runtime: false}, {:mock, "~> 0.3.0", only: [:test], runtime: false},
{:phoenix, "~> 1.4"}, {:phoenix, "== 1.4.0"},
{:phoenix_ecto, "~> 4.0"}, {:phoenix_ecto, "~> 4.0"},
{:phoenix_html, "~> 2.10"}, {:phoenix_html, "~> 2.10"},
{:phoenix_live_reload, "~> 1.2", only: [:dev]}, {:phoenix_live_reload, "~> 1.2", only: [:dev]},

@ -2266,7 +2266,7 @@ defmodule BlockScoutWeb.API.RPC.AddressControllerTest do
end end
test "returns all the required fields", %{conn: conn} do test "returns all the required fields", %{conn: conn} do
%{block_range: range} = emission_reward = insert(:emission_reward) %{block_range: range} = insert(:emission_reward)
block = insert(:block, number: Enum.random(Range.new(range.from, range.to))) block = insert(:block, number: Enum.random(Range.new(range.from, range.to)))
@ -2274,17 +2274,10 @@ defmodule BlockScoutWeb.API.RPC.AddressControllerTest do
|> insert(gas_price: 1) |> insert(gas_price: 1)
|> with_block(block, gas_used: 1) |> with_block(block, gas_used: 1)
expected_reward =
emission_reward.reward
|> Wei.to(:wei)
|> Decimal.add(Decimal.new(1))
|> Wei.from(:wei)
expected_result = [ expected_result = [
%{ %{
"blockNumber" => to_string(block.number), "blockNumber" => to_string(block.number),
"timeStamp" => to_string(block.timestamp), "timeStamp" => to_string(block.timestamp)
"blockReward" => to_string(expected_reward.value)
} }
] ]
@ -2306,7 +2299,7 @@ defmodule BlockScoutWeb.API.RPC.AddressControllerTest do
end end
test "with a block with one transaction", %{conn: conn} do test "with a block with one transaction", %{conn: conn} do
%{block_range: range} = emission_reward = insert(:emission_reward) %{block_range: range} = insert(:emission_reward)
block = insert(:block, number: Enum.random(Range.new(range.from, range.to))) block = insert(:block, number: Enum.random(Range.new(range.from, range.to)))
@ -2314,12 +2307,6 @@ defmodule BlockScoutWeb.API.RPC.AddressControllerTest do
|> insert(gas_price: 1) |> insert(gas_price: 1)
|> with_block(block, gas_used: 1) |> with_block(block, gas_used: 1)
expected_reward =
emission_reward.reward
|> Wei.to(:wei)
|> Decimal.add(Decimal.new(1))
|> Wei.from(:wei)
params = %{ params = %{
"module" => "account", "module" => "account",
"action" => "getminedblocks", "action" => "getminedblocks",
@ -2329,8 +2316,7 @@ defmodule BlockScoutWeb.API.RPC.AddressControllerTest do
expected_result = [ expected_result = [
%{ %{
"blockNumber" => to_string(block.number), "blockNumber" => to_string(block.number),
"timeStamp" => to_string(block.timestamp), "timeStamp" => to_string(block.timestamp)
"blockReward" => to_string(expected_reward.value)
} }
] ]
@ -2346,7 +2332,7 @@ defmodule BlockScoutWeb.API.RPC.AddressControllerTest do
end end
test "with pagination options", %{conn: conn} do test "with pagination options", %{conn: conn} do
%{block_range: range} = emission_reward = insert(:emission_reward) %{block_range: range} = insert(:emission_reward)
block_numbers = Range.new(range.from, range.to) block_numbers = Range.new(range.from, range.to)
@ -2361,12 +2347,6 @@ defmodule BlockScoutWeb.API.RPC.AddressControllerTest do
|> insert(gas_price: 2) |> insert(gas_price: 2)
|> with_block(block2, gas_used: 2) |> with_block(block2, gas_used: 2)
expected_reward =
emission_reward.reward
|> Wei.to(:wei)
|> Decimal.add(Decimal.new(4))
|> Wei.from(:wei)
params = %{ params = %{
"module" => "account", "module" => "account",
"action" => "getminedblocks", "action" => "getminedblocks",
@ -2380,8 +2360,7 @@ defmodule BlockScoutWeb.API.RPC.AddressControllerTest do
expected_result = [ expected_result = [
%{ %{
"blockNumber" => to_string(block2.number), "blockNumber" => to_string(block2.number),
"timeStamp" => to_string(block2.timestamp), "timeStamp" => to_string(block2.timestamp)
"blockReward" => to_string(expected_reward.value)
} }
] ]
@ -2683,7 +2662,7 @@ defmodule BlockScoutWeb.API.RPC.AddressControllerTest do
}) })
end end
defp resolve_schema(result \\ %{}) do defp resolve_schema(result) do
%{ %{
"type" => "object", "type" => "object",
"properties" => %{ "properties" => %{

@ -182,4 +182,5 @@ defmodule EthereumJSONRPC.Parity.FetchedBeneficiaries do
defp get_address_type(reward_type, index) when reward_type == "external" and index == 10, do: :validator defp get_address_type(reward_type, index) when reward_type == "external" and index == 10, do: :validator
defp get_address_type(reward_type, _index) when reward_type == "block", do: :validator defp get_address_type(reward_type, _index) when reward_type == "block", do: :validator
defp get_address_type(reward_type, _index) when reward_type == "uncle", do: :uncle defp get_address_type(reward_type, _index) when reward_type == "uncle", do: :uncle
defp get_address_type(reward_type, _index) when reward_type == "emptyStep", do: :validator
end end

@ -1,27 +1,8 @@
defmodule EthereumJSONRPC.RollingWindowTest do defmodule EthereumJSONRPC.RollingWindowTest do
use ExUnit.Case, use ExUnit.Case, async: true
# The same named process is used for all tests and they use the same key in the table, so they would interfere
async: false
alias EthereumJSONRPC.RollingWindow alias EthereumJSONRPC.RollingWindow
@table :table
setup do
# We set `window_length` to a large time frame so that we can sweep manually to simulate
# time passing
{:ok, pid} =
RollingWindow.start_link([table: @table, duration: :timer.minutes(120), window_count: 3], name: RollingWindow)
on_exit(fn -> Process.exit(pid, :normal) end)
:ok
end
defp sweep do
GenServer.call(RollingWindow, :sweep)
end
test "start_link/2" do test "start_link/2" do
assert {:ok, _} = RollingWindow.start_link(table: :test_table, duration: 5, window_count: 1) assert {:ok, _} = RollingWindow.start_link(table: :test_table, duration: 5, window_count: 1)
end end
@ -29,7 +10,7 @@ defmodule EthereumJSONRPC.RollingWindowTest do
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 divisble by window_count" do
assert_raise ArgumentError, ~r"evenly divisible", fn -> assert_raise ArgumentError, ~r"evenly divisible", fn ->
RollingWindow.init(table: @table, duration: :timer.seconds(2), window_count: 3) RollingWindow.init(table: :init_test_table, duration: :timer.seconds(2), window_count: 3)
end end
end end
@ -40,61 +21,85 @@ defmodule EthereumJSONRPC.RollingWindowTest do
end end
test "when no increments have happened, inspect returns an empty list" do test "when no increments have happened, inspect returns an empty list" do
assert RollingWindow.inspect(@table, :foobar) == [] table = :no_increments_have_happened
start_rolling_window(table)
assert RollingWindow.inspect(table, :foobar) == []
end end
test "when no increments have happened, count returns 0" do test "when no increments have happened, count returns 0" do
assert RollingWindow.count(@table, :foobar) == 0 table = :no_increments_have_happened_empty_list
start_rolling_window(table)
assert RollingWindow.count(table, :foobar) == 0
end end
test "when an increment has happened, inspect returns the count for that window" do test "when an increment has happened, inspect returns the count for that window" do
RollingWindow.inc(@table, :foobar) table = :no_increments_have_happened_count
start_rolling_window(table)
assert RollingWindow.inspect(@table, :foobar) == [1] RollingWindow.inc(table, :foobar)
assert RollingWindow.inspect(table, :foobar) == [1]
end end
test "when an increment has happened, count returns the count for that window" do test "when an increment has happened, count returns the count for that window" do
RollingWindow.inc(@table, :foobar) table = :no_increments_have_happened_count1
start_rolling_window(table)
RollingWindow.inc(table, :foobar)
assert RollingWindow.count(@table, :foobar) == 1 assert RollingWindow.count(table, :foobar) == 1
end end
test "when an increment has happened in multiple windows, inspect returns the count for both windows" do test "when an increment has happened in multiple windows, inspect returns the count for both windows" do
RollingWindow.inc(@table, :foobar) table = :no_increments_have_happened_multiple_windows
sweep() start_rolling_window(table)
RollingWindow.inc(@table, :foobar)
assert RollingWindow.inspect(@table, :foobar) == [1, 1] RollingWindow.inc(table, :foobar)
sweep(table)
RollingWindow.inc(table, :foobar)
assert RollingWindow.inspect(table, :foobar) == [1, 1]
end end
test "when an increment has happened in multiple windows, count returns the sum of both windows" do test "when an increment has happened in multiple windows, count returns the sum of both windows" do
RollingWindow.inc(@table, :foobar) table = :no_increments_have_happened_multiple_windows1
sweep() start_rolling_window(table)
RollingWindow.inc(@table, :foobar)
RollingWindow.inc(table, :foobar)
sweep(table)
RollingWindow.inc(table, :foobar)
assert RollingWindow.count(@table, :foobar) == 2 assert RollingWindow.count(table, :foobar) == 2
end end
test "when an increment has happened, but has been swept <window_count> times, it no longer appears in inspect" do test "when an increment has happened, but has been swept <window_count> times, it no longer appears in inspect" do
RollingWindow.inc(@table, :foobar) table = :no_increments_have_happened_multiple_windows3
sweep() start_rolling_window(table)
sweep()
RollingWindow.inc(@table, :foobar) RollingWindow.inc(table, :foobar)
sweep() sweep(table)
RollingWindow.inc(@table, :foobar) sweep(table)
RollingWindow.inc(table, :foobar)
assert RollingWindow.inspect(@table, :foobar) == [1, 1, 0] sweep(table)
RollingWindow.inc(table, :foobar)
assert RollingWindow.inspect(table, :foobar) == [1, 1, 0]
end end
test "when an increment has happened, but has been swept <window_count> times, it no longer is included in count" do test "when an increment has happened, but has been swept <window_count> times, it no longer is included in count" do
RollingWindow.inc(@table, :foobar) table = :no_increments_have_happened_multiple_windows4
sweep() start_rolling_window(table)
sweep()
RollingWindow.inc(@table, :foobar) RollingWindow.inc(table, :foobar)
sweep() sweep(table)
RollingWindow.inc(@table, :foobar) sweep(table)
RollingWindow.inc(table, :foobar)
assert RollingWindow.count(@table, :foobar) == 2 sweep(table)
RollingWindow.inc(table, :foobar)
assert RollingWindow.count(table, :foobar) == 2
end end
test "sweeping schedules another sweep" do test "sweeping schedules another sweep" do
@ -102,4 +107,13 @@ defmodule EthereumJSONRPC.RollingWindowTest do
RollingWindow.handle_info(:sweep, state) RollingWindow.handle_info(:sweep, state)
assert_receive(:sweep) assert_receive(:sweep)
end end
defp start_rolling_window(table_name) do
{:ok, _pid} =
RollingWindow.start_link([table: table_name, duration: :timer.minutes(120), window_count: 3], name: table_name)
end
defp sweep(name) do
GenServer.call(name, :sweep)
end
end end

@ -27,7 +27,7 @@ config :explorer, Explorer.Counters.AverageBlockTime,
enabled: true, enabled: true,
period: average_block_period period: average_block_period
config :explorer, Explorer.ChainSpec.GenesisData, enabled: true, chain_spec_path: System.get_env("CHAIN_SPEC_PATH") config :explorer, Explorer.ChainSpec.GenesisData, enabled: false, chain_spec_path: System.get_env("CHAIN_SPEC_PATH")
config :explorer, Explorer.Chain.Cache.BlockNumber, enabled: true config :explorer, Explorer.Chain.Cache.BlockNumber, enabled: true

@ -2967,6 +2967,13 @@ defmodule Explorer.Chain do
|> CoinBalance.fetch_coin_balances(paging_options) |> CoinBalance.fetch_coin_balances(paging_options)
|> page_coin_balances(paging_options) |> page_coin_balances(paging_options)
|> Repo.all() |> Repo.all()
|> Enum.dedup_by(fn record ->
if record.delta == Decimal.new(0) do
:dup
else
System.unique_integer()
end
end)
end end
def get_coin_balance(address_hash, block_number) do def get_coin_balance(address_hash, block_number) do

@ -18,7 +18,6 @@ defmodule Explorer.ChainSpec.GenesisData do
@impl GenServer @impl GenServer
def init(_) do def init(_) do
:timer.send_interval(@interval, :import)
Process.send_after(self(), :import, @interval) Process.send_after(self(), :import, @interval)
{:ok, %{}} {:ok, %{}}

@ -8,8 +8,7 @@ defmodule Explorer.Etherscan do
alias Explorer.Etherscan.Logs alias Explorer.Etherscan.Logs
alias Explorer.{Chain, Repo} alias Explorer.{Chain, Repo}
alias Explorer.Chain.Address.TokenBalance alias Explorer.Chain.Address.TokenBalance
alias Explorer.Chain.{Block, Hash, InternalTransaction, Transaction, Wei} alias Explorer.Chain.{Block, Hash, InternalTransaction, Transaction}
alias Explorer.Chain.Block.EmissionReward
@default_options %{ @default_options %{
order_by_direction: :asc, order_by_direction: :asc,
@ -187,22 +186,15 @@ defmodule Explorer.Etherscan do
query = query =
from( from(
b in Block, b in Block,
left_join: t in assoc(b, :transactions),
inner_join: r in EmissionReward,
on: fragment("? <@ ?", b.number, r.block_range),
where: b.miner_hash == ^address_hash, where: b.miner_hash == ^address_hash,
order_by: [desc: b.number], order_by: [desc: b.number],
group_by: b.number, group_by: b.number,
group_by: b.timestamp, group_by: b.timestamp,
group_by: r.reward,
limit: ^merged_options.page_size, limit: ^merged_options.page_size,
offset: ^offset(merged_options), offset: ^offset(merged_options),
select: %{ select: %{
number: b.number, number: b.number,
timestamp: b.timestamp, timestamp: b.timestamp
reward: %Wei{
value: fragment("coalesce(sum(? * ?), 0) + ?", t.gas_used, t.gas_price, r.reward)
}
} }
) )

@ -115,6 +115,14 @@ defmodule Explorer.SmartContract.Verifier do
|> Enum.reverse() |> Enum.reverse()
|> :binary.list_to_bin() |> :binary.list_to_bin()
# Solidity >= 0.5.11 https://github.com/ethereum/solidity/blob/develop/Changelog.md#0511-2019-08-12
# Metadata: Update the swarm hash to the current specification, changes bzzr0 to bzzr1 and urls to use bzz-raw://
"a265627a7a72315820" <>
<<_::binary-size(64)>> <> "64736f6c6343" <> <<_::binary-size(6)>> <> "0032" <> _constructor_arguments ->
extracted
|> Enum.reverse()
|> :binary.list_to_bin()
<<next::binary-size(2)>> <> rest -> <<next::binary-size(2)>> <> rest ->
do_extract_bytecode([next | extracted], rest) do_extract_bytecode([next | extracted], rest)
end end

@ -48,6 +48,16 @@ defmodule Explorer.SmartContract.Verifier.ConstructorArguments do
extract_constructor_arguments(constructor_arguments, passed_constructor_arguments) extract_constructor_arguments(constructor_arguments, passed_constructor_arguments)
end end
# Solidity >= 0.5.11 https://github.com/ethereum/solidity/blob/develop/Changelog.md#0511-2019-08-12
# Metadata: Update the swarm hash to the current specification, changes bzzr0 to bzzr1 and urls to use bzz-raw://
"a265627a7a72315820" <>
<<_::binary-size(64)>> <> "64736f6c6343" <> <<_::binary-size(6)>> <> "0032" <> constructor_arguments ->
if passed_constructor_arguments == constructor_arguments do
true
else
extract_constructor_arguments(constructor_arguments, passed_constructor_arguments)
end
<<>> -> <<>> ->
passed_constructor_arguments == "" passed_constructor_arguments == ""

@ -4159,4 +4159,30 @@ defmodule Explorer.ChainTest do
assert Chain.staking_pools_count(:inactive) == 1 assert Chain.staking_pools_count(:inactive) == 1
end end
end end
describe "address_to_coin_balances/2" do
test "deduplicates records by zero delta" do
address = insert(:address)
1..5
|> Enum.each(fn block_number ->
insert(:block, number: block_number)
insert(:fetched_balance, value: 1, block_number: block_number, address_hash: address.hash)
end)
insert(:block, number: 6)
insert(:fetched_balance, value: 2, block_number: 6, address_hash: address.hash)
assert [first, second, third] = Chain.address_to_coin_balances(address.hash, [])
assert first.block_number == 6
assert first.delta == Decimal.new(1)
assert second.block_number == 5
assert second.delta == Decimal.new(0)
assert third.block_number == 1
assert third.delta == Decimal.new(1)
end
end
end end

@ -4,7 +4,7 @@ defmodule Explorer.EtherscanTest do
import Explorer.Factory import Explorer.Factory
alias Explorer.{Etherscan, Chain} alias Explorer.{Etherscan, Chain}
alias Explorer.Chain.{Transaction, Wei} alias Explorer.Chain.Transaction
describe "list_transactions/2" do describe "list_transactions/2" do
test "with empty db" do test "with empty db" do
@ -1170,7 +1170,7 @@ defmodule Explorer.EtherscanTest do
describe "list_blocks/1" do describe "list_blocks/1" do
test "it returns all required fields" do test "it returns all required fields" do
%{block_range: range} = emission_reward = insert(:emission_reward) %{block_range: range} = insert(:emission_reward)
block = insert(:block, number: Enum.random(Range.new(range.from, range.to))) block = insert(:block, number: Enum.random(Range.new(range.from, range.to)))
@ -1181,17 +1181,10 @@ defmodule Explorer.EtherscanTest do
|> insert(gas_price: 1) |> insert(gas_price: 1)
|> with_block(block, gas_used: 1) |> with_block(block, gas_used: 1)
expected_reward =
emission_reward.reward
|> Wei.to(:wei)
|> Decimal.add(Decimal.new(1))
|> Wei.from(:wei)
expected = [ expected = [
%{ %{
number: block.number, number: block.number,
timestamp: block.timestamp, timestamp: block.timestamp
reward: expected_reward
} }
] ]
@ -1199,32 +1192,14 @@ defmodule Explorer.EtherscanTest do
end end
test "with block containing multiple transactions" do test "with block containing multiple transactions" do
%{block_range: range} = emission_reward = insert(:emission_reward) %{block_range: range} = insert(:emission_reward)
block = insert(:block, number: Enum.random(Range.new(range.from, range.to))) block = insert(:block, number: Enum.random(Range.new(range.from, range.to)))
# irrelevant transaction
insert(:transaction)
:transaction
|> insert(gas_price: 1)
|> with_block(block, gas_used: 1)
:transaction
|> insert(gas_price: 1)
|> with_block(block, gas_used: 2)
expected_reward =
emission_reward.reward
|> Wei.to(:wei)
|> Decimal.add(Decimal.new(3))
|> Wei.from(:wei)
expected = [ expected = [
%{ %{
number: block.number, number: block.number,
timestamp: block.timestamp, timestamp: block.timestamp
reward: expected_reward
} }
] ]
@ -1232,7 +1207,7 @@ defmodule Explorer.EtherscanTest do
end end
test "with block without transactions" do test "with block without transactions" do
%{block_range: range} = emission_reward = insert(:emission_reward) %{block_range: range} = insert(:emission_reward)
block = insert(:block, number: Enum.random(Range.new(range.from, range.to))) block = insert(:block, number: Enum.random(Range.new(range.from, range.to)))
@ -1242,8 +1217,7 @@ defmodule Explorer.EtherscanTest do
expected = [ expected = [
%{ %{
number: block.number, number: block.number,
timestamp: block.timestamp, timestamp: block.timestamp
reward: emission_reward.reward
} }
] ]
@ -1251,7 +1225,7 @@ defmodule Explorer.EtherscanTest do
end end
test "with multiple blocks" do test "with multiple blocks" do
%{block_range: range} = emission_reward = insert(:emission_reward) %{block_range: range} = insert(:emission_reward)
block_numbers = Range.new(range.from, range.to) block_numbers = Range.new(range.from, range.to)
@ -1262,47 +1236,14 @@ defmodule Explorer.EtherscanTest do
block1 = insert(:block, number: block_number1, miner: address) block1 = insert(:block, number: block_number1, miner: address)
block2 = insert(:block, number: block_number2, miner: address) block2 = insert(:block, number: block_number2, miner: address)
# irrelevant transaction
insert(:transaction)
:transaction
|> insert(gas_price: 2)
|> with_block(block1, gas_used: 2)
:transaction
|> insert(gas_price: 2)
|> with_block(block1, gas_used: 2)
:transaction
|> insert(gas_price: 3)
|> with_block(block2, gas_used: 3)
:transaction
|> insert(gas_price: 3)
|> with_block(block2, gas_used: 3)
expected_reward_block1 =
emission_reward.reward
|> Wei.to(:wei)
|> Decimal.add(Decimal.new(8))
|> Wei.from(:wei)
expected_reward_block2 =
emission_reward.reward
|> Wei.to(:wei)
|> Decimal.add(Decimal.new(18))
|> Wei.from(:wei)
expected = [ expected = [
%{ %{
number: block2.number, number: block2.number,
timestamp: block2.timestamp, timestamp: block2.timestamp
reward: expected_reward_block2
}, },
%{ %{
number: block1.number, number: block1.number,
timestamp: block1.timestamp, timestamp: block1.timestamp
reward: expected_reward_block1
} }
] ]
@ -1310,7 +1251,7 @@ defmodule Explorer.EtherscanTest do
end end
test "with pagination options" do test "with pagination options" do
%{block_range: range} = emission_reward = insert(:emission_reward) %{block_range: range} = insert(:emission_reward)
block_numbers = Range.new(range.from, range.to) block_numbers = Range.new(range.from, range.to)
@ -1321,29 +1262,17 @@ defmodule Explorer.EtherscanTest do
block1 = insert(:block, number: block_number1, miner: address) block1 = insert(:block, number: block_number1, miner: address)
block2 = insert(:block, number: block_number2, miner: address) block2 = insert(:block, number: block_number2, miner: address)
:transaction
|> insert(gas_price: 2)
|> with_block(block1, gas_used: 2)
expected_reward =
emission_reward.reward
|> Wei.to(:wei)
|> Decimal.add(Decimal.new(4))
|> Wei.from(:wei)
expected1 = [ expected1 = [
%{ %{
number: block2.number, number: block2.number,
timestamp: block2.timestamp, timestamp: block2.timestamp
reward: emission_reward.reward
} }
] ]
expected2 = [ expected2 = [
%{ %{
number: block1.number, number: block1.number,
timestamp: block1.timestamp, timestamp: block1.timestamp
reward: expected_reward
} }
] ]

@ -56,6 +56,33 @@ defmodule Explorer.SmartContract.VerifierTest do
assert abi != nil assert abi != nil
end end
test "verifies smart contract with new `whisper` metadata (bzz0 => bzz1) in solidity 0.5.11" do
contract_data =
"#{File.cwd!()}/test/support/fixture/smart_contract/solidity_5.11_new_whisper_metadata.json"
|> File.read!()
|> Jason.decode!()
compiler_version = contract_data["compiler_version"]
name = contract_data["name"]
optimize = false
contract = contract_data["contract"]
expected_bytecode = contract_data["bytecode"]
evm_version = contract_data["evm_version"]
contract_address = insert(:contract_address, contract_code: "0x" <> expected_bytecode)
params = %{
"contract_source_code" => contract,
"compiler_version" => compiler_version,
"evm_version" => evm_version,
"name" => name,
"optimization" => optimize
}
assert {:ok, %{abi: abi}} = Verifier.evaluate_authenticity(contract_address.hash, params)
assert abi != nil
end
test "verifies smart contract with constructor arguments", %{ test "verifies smart contract with constructor arguments", %{
contract_code_info: contract_code_info contract_code_info: contract_code_info
} do } do

@ -183,7 +183,7 @@ defmodule Indexer.Block.Fetcher do
end end
end end
defp update_block_cache(blocks) do defp update_block_cache(blocks) when is_list(blocks) do
max_block = Enum.max_by(blocks, fn block -> block.number end) max_block = Enum.max_by(blocks, fn block -> block.number end)
min_block = Enum.min_by(blocks, fn block -> block.number end) min_block = Enum.min_by(blocks, fn block -> block.number end)
@ -192,6 +192,8 @@ defmodule Indexer.Block.Fetcher do
BlocksCache.update(blocks) BlocksCache.update(blocks)
end end
defp update_block_cache(_), do: :ok
defp update_transactions_cache(transactions) do defp update_transactions_cache(transactions) do
Transactions.update(transactions) Transactions.update(transactions)
end end

@ -14,52 +14,54 @@ $ export NETWORK=POA
``` ```
| Variable | Required | Description | Default | Version | | Variable | Required | Description | Default | Version | Need recompile |
| --- | --- | --- | ---| --- | | --- | --- | --- | ---| --- | --- |
| `NETWORK`| :white_check_mark: | Environment variable for the main EVM network such as Ethereum Network or POA Network | POA Network | all | | `NETWORK`| :white_check_mark: | Environment variable for the main EVM network such as Ethereum Network or POA Network | POA Network | all | |
| `SUBNETWORK` | :white_check_mark: | Environment variable for the subnetwork such as Core or Sokol Network | Sokol Testnet | all | | `SUBNETWORK` | :white_check_mark: | Environment variable for the subnetwork such as Core or Sokol Network | Sokol Testnet | all | |
| `NETWORK_ICON` | :white_check_mark: | Environment variable for the main network icon or testnet icon. Two options are `_test_network_icon.html` and `_network_icon.html` | `_test_network_icon.html` | all | | `NETWORK_ICON` | :white_check_mark: | Environment variable for the main network icon or testnet icon. Two options are `_test_network_icon.html` and `_network_icon.html` | `_test_network_icon.html` | all | |
| `LOGO` | :white_check_mark: | Environment variable for the logo image location. The logo files names for different chains can be found [here](https://github.com/poanetwork/blockscout/tree/master/apps/block_scout_web/assets/static/images) | /images/blockscout_logo.svg | all | | `LOGO` | :white_check_mark: | Environment variable for the logo image location. The logo files names for different chains can be found [here](https://github.com/poanetwork/blockscout/tree/master/apps/block_scout_web/assets/static/images) | /images/blockscout_logo.svg | all | |
| `ETHEREUM_JSONRPC_VARIANT` | :white_check_mark: | This environment variable is used to tell the application which RPC Client the node is using (i.e. Geth, Parity, or Ganache) | parity | all | | `ETHEREUM_JSONRPC_VARIANT` | :white_check_mark: | This environment variable is used to tell the application which RPC Client the node is using (i.e. Geth, Parity, or Ganache) | parity | all | |
| `ETHEREUM_JSONRPC_HTTP_URL` | :white_check_mark: | The RPC endpoint used to fetch blocks, transactions, receipts, tokens. | localhost:8545 | all | | `ETHEREUM_JSONRPC_HTTP_URL` | :white_check_mark: | The RPC endpoint used to fetch blocks, transactions, receipts, tokens. | localhost:8545 | all | |
| `ETHEREUM_JSONRPC_TRACE_URL` | | The RPC endpoint specifically for the Geth/Parity client used by trace_block and trace_replayTransaction. This can be used to designate a tracing node. | localhost:8545 | all | | `ETHEREUM_JSONRPC_TRACE_URL` | | The RPC endpoint specifically for the Geth/Parity client used by trace_block and trace_replayTransaction. This can be used to designate a tracing node. | localhost:8545 | all | |
| `ETHEREUM_JSONRPC_WS_URL` | :white_check_mark: | The WebSockets RPC endpoint used to subscribe to the `newHeads` subscription alerting the indexer to fetch new blocks. | ws://localhost:8546 | all | | `ETHEREUM_JSONRPC_WS_URL` | :white_check_mark: | The WebSockets RPC endpoint used to subscribe to the `newHeads` subscription alerting the indexer to fetch new blocks. | ws://localhost:8546 | all | |
| `NETWORK_PATH` | | Used to set a network path other than what is displayed in the root directory. An example would be to add /eth/mainnet/ to the root directory. | (empty) | all | | `NETWORK_PATH` | | Used to set a network path other than what is displayed in the root directory. An example would be to add /eth/mainnet/ to the root directory. | (empty) | all | |
| `SECRET_KEY_BASE` | :white_check_mark: | Use mix phx.gen.secret to generate a new Secret Key Base string to protect production assets. | (empty) | all | | `SECRET_KEY_BASE` | :white_check_mark: | Use mix phx.gen.secret to generate a new Secret Key Base string to protect production assets. | (empty) | all | |
| `CHECK_ORIGIN` | | Used to check the origin of requests when the origin header is present. It defaults to false. In case of true, it will check against the host value. | false | all | | `CHECK_ORIGIN` | | Used to check the origin of requests when the origin header is present. It defaults to false. In case of true, it will check against the host value. | false | all | |
| `PORT` | :white_check_mark: | Default port the application runs on is 4000 | 4000 | all | | `PORT` | :white_check_mark: | Default port the application runs on is 4000 | 4000 | all | |
| `COIN` | :white_check_mark: | The coin here is checked via the Coinmarketcap API to obtain USD prices on graphs and other areas of the UI | POA | all | | `COIN` | :white_check_mark: | The coin here is checked via the Coinmarketcap API to obtain USD prices on graphs and other areas of the UI | POA | all | |
| `METADATA_CONTRACT` | | This environment variable is specifically used by POA Network to obtain Validators information to display in the UI. | (empty) | all | | `METADATA_CONTRACT` | | This environment variable is specifically used by POA Network to obtain Validators information to display in the UI. | (empty) | all | |
| `VALIDATORS_CONTRACT` | | This environment variable is specifically used by POA Network to obtain the Emission Fund contract. | (empty) | all | | `VALIDATORS_CONTRACT` | | This environment variable is specifically used by POA Network to obtain the Emission Fund contract. | (empty) | all | |
| `SUPPLY_MODULE` | | This environment variable is used by the xDai Chain in order to tell the application how to calculate the total supply of the chain. | false | all | | `SUPPLY_MODULE` | | This environment variable is used by the xDai Chain in order to tell the application how to calculate the total supply of the chain. | false | all | |
| `SOURCE_MODULE` | | This environment variable is used to calculate the exchange rate and is specifically used by the xDai Chain. | false | all | | `SOURCE_MODULE` | | This environment variable is used to calculate the exchange rate and is specifically used by the xDai Chain. | false | all | |
| `DATABASE_URL` | | Production environment variable to define the Database endpoint. | (empty) | all | | `DATABASE_URL` | | Production environment variable to define the Database endpoint. | (empty) | all | |
| `POOL_SIZE` | | Production environment variable to define the number of database connections allowed. | 20 | all | | `POOL_SIZE` | | Production environment variable to define the number of database connections allowed. | 20 | all | |
| `ECTO_USE_SSL` | | Production environment variable to use SSL on Ecto queries. | true | all | | `ECTO_USE_SSL` | | Production environment variable to use SSL on Ecto queries. | true | all | |
| `DATADOG_HOST` | | Host configuration setting for [Datadog integration](https://docs.datadoghq.com/integrations/) | (empty) | all | | `DATADOG_HOST` | | Host configuration setting for [Datadog integration](https://docs.datadoghq.com/integrations/) | (empty) | all | |
| `DATADOG_PORT` | | Port configuration setting for [Datadog integration](https://docs.datadoghq.com/integrations/). | (empty} | all | | `DATADOG_PORT` | | Port configuration setting for [Datadog integration](https://docs.datadoghq.com/integrations/). | (empty} | all | |
| `SPANDEX_BATCH_SIZE` | | [Spandex](https://github.com/spandex-project/spandex) and Datadog configuration setting. | (empty) | all | | `SPANDEX_BATCH_SIZE` | | [Spandex](https://github.com/spandex-project/spandex) and Datadog configuration setting. | (empty) | all |
| `SPANDEX_SYNC_THRESHOLD` | | [Spandex](https://github.com/spandex-project/spandex) and Datadog configuration setting. | (empty) | all | | `SPANDEX_SYNC_THRESHOLD` | | [Spandex](https://github.com/spandex-project/spandex) and Datadog configuration setting. | (empty) | all | |
| `HEART_BEAT_TIMEOUT` | | Production environment variable to restart the application in the event of a crash. | 30 | all | | `HEART_BEAT_TIMEOUT` | | Production environment variable to restart the application in the event of a crash. | 30 | all | |
| `HEART_COMMAND` | | Production environment variable to restart the application in the event of a crash. | systemctl restart explorer.service | all | | `HEART_COMMAND` | | Production environment variable to restart the application in the event of a crash. | systemctl restart explorer.service | all | |
| `BLOCKSCOUT_VERSION` | | Added to the footer to signify the current BlockScout version. | (empty) | v1.3.4+ | | `BLOCKSCOUT_VERSION` | | Added to the footer to signify the current BlockScout version. | (empty) | v1.3.4+ | |
| `RELEASE_LINK` | | The link to Blockscout release notes in the footer. | <u>https: //github.com/poanetwork/</u> <br /><u>blockscout/releases/</u> <br /> <u>tag/${BLOCKSCOUT_VERSION}</u> | v1.3.5+ | | `RELEASE_LINK` | | The link to Blockscout release notes in the footer. | <u>https: //github.com/poanetwork/</u> <br /><u>blockscout/releases/</u> <br /> <u>tag/${BLOCKSCOUT_VERSION}</u> | v1.3.5+ | |
| `ELIXIR_VERSION` | | Elixir version to install on the node before Blockscout deploy. | (empty) | all | | `ELIXIR_VERSION` | | Elixir version to install on the node before Blockscout deploy. | (empty) | all | |
| `BLOCK_TRANSFORMER` | | Transformer for blocks: base or clique. | base | v1.3.4+ | | `BLOCK_TRANSFORMER` | | Transformer for blocks: base or clique. | base | v1.3.4+ | |
| `GRAPHIQL _TRANSACTION` | | Default transaction in query to GraphiQL. | (empty) | v1.3.4+ | | `GRAPHIQL_TRANSACTION` | | Default transaction in query to GraphiQL. | (empty) | v1.2.0+ | :white_check_mark: |
| `FIRST_BLOCK` | | The block number, where indexing begins from. | 0 | v1.3.8+ | | `FIRST_BLOCK` | | The block number, where indexing begins from. | 0 | v1.3.8+ | |
| `LAST_BLOCK` | | The block number, where indexing stops. | (empty) | v2.0.3+ | | `LAST_BLOCK` | | The block number, where indexing stops. | (empty) | v2.0.3+ | |
| `TXS_COUNT_CACHE_PERIOD` | | Interval in seconds to restart the task, which calculates the total txs count. | 60 * 60 * 2 | v1.3.9+ | | `TXS_COUNT_CACHE_PERIOD` | | Interval in seconds to restart the task, which calculates the total txs count. | 60 * 60 * 2 | v1.3.9+ | |
| `ADDRESS_WITH_BALANCES` <br /> `_UPDATE_INTERVAL`| | Interval in seconds to restart the task, which calculates addresses with balances. | 30 * 60 | v1.3.9+ | | `ADDRESS_WITH_BALANCES` <br /> `_UPDATE_INTERVAL`| | Interval in seconds to restart the task, which calculates addresses with balances. | 30 * 60 | v1.3.9+ | |
| `LINK_TO_OTHER_EXPLORERS` | | true/false. If true, links to other explorers are added in the footer | (empty) | v1.3.0+ | | `LINK_TO_OTHER_EXPLORERS` | | true/false. If true, links to other explorers are added in the footer | (empty) | v1.3.0+ | |
| `COINMARKETCAP_PAGES` | | the number of pages on coinmarketcap to list in order to find token's price | 10 | v1.3.10+ | | `COINMARKETCAP_PAGES` | | the number of pages on coinmarketcap to list in order to find token's price | 10 | v1.3.10+ | |
| `CHAIN_SPEC_PATH` | | Chain specification path (absolute file system path or url) to import block emission reward ranges and genesis account balances from | (empty) | master | | `SUPPORTED_CHAINS` | | Array of supported chains that displays in the footer and in the chains dropdown. This var was introduced in this PR [#1900](https://github.com/poanetwork/blockscout/pull/1900) and looks like an array of JSON objects. | (empty) | v2.0.0+ | |
| `SUPPORTED_CHAINS` | | Array of supported chains that displays in the footer and in the chains dropdown. This var was introduced in this PR [#1900](https://github.com/poanetwork/blockscout/pull/1900) and looks like an array of JSON objects. | (empty) | v2.0.0+ | | `BLOCK_COUNT_CACHE_PERIOD ` | | time to live of cache in seconds. This var was introduced in [#1876](https://github.com/poanetwork/blockscout/pull/1876) | 600 | v2.0.0+ | |
| `BLOCK_COUNT_CACHE_PERIOD ` | | time to live of cache in seconds. This var was introduced in [#1876](https://github.com/poanetwork/blockscout/pull/1876) | 600 | v2.0.0+ | | `ALLOWED_EVM_VERSIONS ` | | the comma-separated list of allowed EVM versions for contracts verification. This var was introduced in [#1964](https://github.com/poanetwork/blockscout/pull/1964) | "homestead, tangerineWhistle, spuriousDragon, byzantium, constantinople, petersburg" | v2.0.0+ | |
| `ALLOWED_EVM_VERSIONS ` | | the comma-separated list of allowed EVM versions for contracts verification. This var was introduced in [#1964](https://github.com/poanetwork/blockscout/pull/1964) | "homestead, tangerineWhistle, spuriousDragon, byzantium, constantinople, petersburg" | v2.0.0+ | | `AVERAGE_BLOCK_CACHE_PERIOD` | | Update of average block cache, in seconds | 30 minutes | v2.0.2+ |
| `DISABLE_WEBAPP` | | If `true`, endpoints to webapp are hidden (compile-time) | `false` | v2.0.3+ | | `MARKET_HISTORY_CACHE_PERIOD` | | Update of market history cache, in seconds | 6 hours | v2.0.2+ |
| `DISABLE_READ_API` | | If `true`, read-only endpoints to API are hidden (compile-time) | `false` | v2.0.3+ | | `DISABLE_WEBAPP` | | If `true`, endpoints to webapp are hidden (compile-time) | `false` | v2.0.3+ | :white_check_mark: |
| `DISABLE_WRITE_API` | | If `true`, write endpoints to API are hidden (compile-time) | `false` | v2.0.3+ | | `DISABLE_READ_API` | | If `true`, read-only endpoints to API are hidden (compile-time) | `false` | v2.0.3+ | :white_check_mark: |
| `DISABLE_INDEXER` | | If `true`, indexer application doesn't run | `false` | v2.0.3+ | | `DISABLE_WRITE_API` | | If `true`, write endpoints to API are hidden (compile-time) | `false` | v2.0.3+ | :white_check_mark: |
| `WEBAPP_URL` | | Link to web application instance, e.g. `http://host/path` | (empty) | v2.0.3+ | | `DISABLE_INDEXER` | | If `true`, indexer application doesn't run | `false` | v2.0.3+ | :white_check_mark: |
| `API_URL` | | Link to API instance, e.g. `http://host/path` | (empty) | v2.0.3+ | | `WEBAPP_URL` | | Link to web application instance, e.g. `http://host/path` | (empty) | v2.0.3+ | |
| `API_URL` | | Link to API instance, e.g. `http://host/path` | (empty) | v2.0.3+ | |
| `CHAIN_SPEC_PATH` | | Chain specification path (absolute file system path or url) to import block emission reward ranges and genesis account balances from | (empty) | master | |

@ -81,7 +81,7 @@
"optimal": {:hex, :optimal, "0.3.6", "46bbf52fbbbd238cda81e02560caa84f93a53c75620f1fe19e81e4ae7b07d1dd", [:mix], [], "hexpm"}, "optimal": {:hex, :optimal, "0.3.6", "46bbf52fbbbd238cda81e02560caa84f93a53c75620f1fe19e81e4ae7b07d1dd", [:mix], [], "hexpm"},
"parallel_stream": {:hex, :parallel_stream, "1.0.6", "b967be2b23f0f6787fab7ed681b4c45a215a81481fb62b01a5b750fa8f30f76c", [:mix], [], "hexpm"}, "parallel_stream": {:hex, :parallel_stream, "1.0.6", "b967be2b23f0f6787fab7ed681b4c45a215a81481fb62b01a5b750fa8f30f76c", [:mix], [], "hexpm"},
"parse_trans": {:hex, :parse_trans, "3.2.0", "2adfa4daf80c14dc36f522cf190eb5c4ee3e28008fc6394397c16f62a26258c2", [:rebar3], [], "hexpm"}, "parse_trans": {:hex, :parse_trans, "3.2.0", "2adfa4daf80c14dc36f522cf190eb5c4ee3e28008fc6394397c16f62a26258c2", [:rebar3], [], "hexpm"},
"phoenix": {:hex, :phoenix, "1.4.9", "746d098e10741c334d88143d3c94cab1756435f94387a63441792e66ec0ee974", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.8.1 or ~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"}, "phoenix": {:hex, :phoenix, "1.4.0", "56fe9a809e0e735f3e3b9b31c1b749d4b436e466d8da627b8d82f90eaae714d2", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}], "hexpm"},
"phoenix_ecto": {:hex, :phoenix_ecto, "4.0.0", "c43117a136e7399ea04ecaac73f8f23ee0ffe3e07acfcb8062fe5f4c9f0f6531", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.9", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, "phoenix_ecto": {:hex, :phoenix_ecto, "4.0.0", "c43117a136e7399ea04ecaac73f8f23ee0ffe3e07acfcb8062fe5f4c9f0f6531", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.9", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
"phoenix_form_awesomplete": {:hex, :phoenix_form_awesomplete, "0.1.5", "d09aade160b584e3428e1e095645482396f17bddda4f566f1118f12d2598d11c", [:mix], [{:phoenix_html, "~> 2.10", [hex: :phoenix_html, repo: "hexpm", optional: false]}], "hexpm"}, "phoenix_form_awesomplete": {:hex, :phoenix_form_awesomplete, "0.1.5", "d09aade160b584e3428e1e095645482396f17bddda4f566f1118f12d2598d11c", [:mix], [{:phoenix_html, "~> 2.10", [hex: :phoenix_html, repo: "hexpm", optional: false]}], "hexpm"},
"phoenix_html": {:hex, :phoenix_html, "2.13.3", "850e292ff6e204257f5f9c4c54a8cb1f6fbc16ed53d360c2b780a3d0ba333867", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, "phoenix_html": {:hex, :phoenix_html, "2.13.3", "850e292ff6e204257f5f9c4c54a8cb1f6fbc16ed53d360c2b780a3d0ba333867", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},

Loading…
Cancel
Save