From 0fe7fee87c29fbe183c1aedbadc1b902c4515b9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Uhl=C3=AD=C5=99?= Date: Thu, 21 May 2020 12:06:33 +0200 Subject: [PATCH] feat: store cache-state data in database --- config/default.json5 | 12 +- package-lock.json | 649 +++++++++++++++++++++---------- package.json | 26 +- src/app.ts | 4 +- src/blockchain/events.ts | 32 +- src/blockchain/utils.ts | 17 +- src/cli/precache.ts | 6 +- src/cli/purge.ts | 6 +- src/conf.ts | 31 -- src/definitions.ts | 13 - src/rates/providers/coingecko.ts | 5 +- src/rns/index.ts | 13 +- src/rns/rns.precache.ts | 16 +- src/storage/index.ts | 9 +- src/store.ts | 17 + src/utils.ts | 36 +- test/blockchain/events.spec.ts | 154 +++++--- 17 files changed, 647 insertions(+), 399 deletions(-) delete mode 100644 src/conf.ts create mode 100644 src/store.ts diff --git a/config/default.json5 b/config/default.json5 index 6e83dea4..48389a06 100644 --- a/config/default.json5 +++ b/config/default.json5 @@ -10,13 +10,6 @@ path: null }, - conf: { - name: 'config', - - // Specifies if configuration using Conf() should be persisted between restarts - persist: true - }, - rates: { enabled: true, provider: 'coingecko', @@ -142,6 +135,11 @@ // If to use polling strategy, if false then listening is used. polling: true } + }, + + // RNS Registrar contract settings used for RNS precache + registrar: { + startingBlock: "genesis" } } } diff --git a/package-lock.json b/package-lock.json index f475d893..927dc52d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1820,6 +1820,114 @@ "web3-utils": "^1.0.0-beta.48" } }, + "@ethersproject/abi": { + "version": "5.0.0-beta.153", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.0-beta.153.tgz", + "integrity": "sha512-aXweZ1Z7vMNzJdLpR1CZUAIgnwjrZeUSvN9syCwlBaEBUFJmFY+HHnfuTI5vIhVs/mRkfJVrbEyl51JZQqyjAg==", + "requires": { + "@ethersproject/address": ">=5.0.0-beta.128", + "@ethersproject/bignumber": ">=5.0.0-beta.130", + "@ethersproject/bytes": ">=5.0.0-beta.129", + "@ethersproject/constants": ">=5.0.0-beta.128", + "@ethersproject/hash": ">=5.0.0-beta.128", + "@ethersproject/keccak256": ">=5.0.0-beta.127", + "@ethersproject/logger": ">=5.0.0-beta.129", + "@ethersproject/properties": ">=5.0.0-beta.131", + "@ethersproject/strings": ">=5.0.0-beta.130" + } + }, + "@ethersproject/address": { + "version": "5.0.0-beta.135", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.0.0-beta.135.tgz", + "integrity": "sha512-y9r/ajYBCDVM1ZD6kKgTRHBOxgURcQ24qTolw3oGyK373XHNrcY9ufDgZ5KR8h0OvLvczb4SGzYhahYvBnyZwA==", + "requires": { + "@ethersproject/bignumber": ">=5.0.0-beta.138", + "@ethersproject/bytes": ">=5.0.0-beta.137", + "@ethersproject/keccak256": ">=5.0.0-beta.131", + "@ethersproject/logger": ">=5.0.0-beta.137", + "@ethersproject/rlp": ">=5.0.0-beta.132", + "bn.js": "^4.4.0" + } + }, + "@ethersproject/bignumber": { + "version": "5.0.0-beta.139", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.0.0-beta.139.tgz", + "integrity": "sha512-h1C1okCmPK3UVWwMGUbuCZykplJmD/TdknPQQHJWL/chK5MqBhyQ5o1Cay7mHXKCBnjWrR9BtwjfkAh76pYtFA==", + "requires": { + "@ethersproject/bytes": ">=5.0.0-beta.137", + "@ethersproject/logger": ">=5.0.0-beta.137", + "@ethersproject/properties": ">=5.0.0-beta.140", + "bn.js": "^4.4.0" + } + }, + "@ethersproject/bytes": { + "version": "5.0.0-beta.138", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.0.0-beta.138.tgz", + "integrity": "sha512-q4vaIthv89RJQ0V6gdzh1xuluJE1uYbnfzBUYTegicaXX6jRTCjDDhyiQhyEnNi7pKrGtuOrR3v3+7WtAR8Imw==", + "requires": { + "@ethersproject/logger": ">=5.0.0-beta.137" + } + }, + "@ethersproject/constants": { + "version": "5.0.0-beta.134", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.0.0-beta.134.tgz", + "integrity": "sha512-tKKL7F3ozL+XgZ4+McNmp12rnPxKf+InKr36asVVAiVLa0WxnNsO9m/+0LkW5dMFbqn2i2VJtBwKfl1OE6GInA==", + "requires": { + "@ethersproject/bignumber": ">=5.0.0-beta.138" + } + }, + "@ethersproject/hash": { + "version": "5.0.0-beta.134", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.0.0-beta.134.tgz", + "integrity": "sha512-yvHyu+9Mgi4jn41DakA8tgHwngsSlTEyLBavP08GN3oS6fTiqflEMa4AXUFndztpcvk7UdGlowCOp6UupbmRVQ==", + "requires": { + "@ethersproject/bytes": ">=5.0.0-beta.137", + "@ethersproject/keccak256": ">=5.0.0-beta.131", + "@ethersproject/logger": ">=5.0.0-beta.137", + "@ethersproject/strings": ">=5.0.0-beta.136" + } + }, + "@ethersproject/keccak256": { + "version": "5.0.0-beta.132", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.0.0-beta.132.tgz", + "integrity": "sha512-YpkwYGV4nu1QM7Q+mhYKO1bCk/sbiV7AAU/HnHwZhDiwJZSDRwfjiFkAJQpvTbsAR02Ek9LhFEBg4OfLTEhJLg==", + "requires": { + "@ethersproject/bytes": ">=5.0.0-beta.137", + "js-sha3": "0.5.7" + } + }, + "@ethersproject/logger": { + "version": "5.0.0-beta.137", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.0.0-beta.137.tgz", + "integrity": "sha512-H36iMhWOY+tco1+o2NZUdQT8Gc6Y9795RSPgvluatvjvyt3X6mHtWXes4F8Rc5N/95px++a/ODYVSkSmlr68+A==" + }, + "@ethersproject/properties": { + "version": "5.0.0-beta.141", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.0.0-beta.141.tgz", + "integrity": "sha512-jWHVLlH8tmdMw6L9USaidZsiY/IOV4Br01PKM711oDZ8McBXrbW1FzcgpuzV91SNNMYek9kvrJJzAOPL2vANTQ==", + "requires": { + "@ethersproject/logger": ">=5.0.0-beta.137" + } + }, + "@ethersproject/rlp": { + "version": "5.0.0-beta.133", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.0.0-beta.133.tgz", + "integrity": "sha512-4zwGZov221uYuz6oXqAf2i5dk3ven7mSNkPRYvS2xdAlUn1Qy8GFUswyRuLaGzpWUGNlKIWCEnvomP5L/CtMPQ==", + "requires": { + "@ethersproject/bytes": ">=5.0.0-beta.137", + "@ethersproject/logger": ">=5.0.0-beta.137" + } + }, + "@ethersproject/strings": { + "version": "5.0.0-beta.137", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.0.0-beta.137.tgz", + "integrity": "sha512-Z1xKXjoBWM5DOlc8HvjpOKO1zZ8kf4nLpf4C8zZjz+GNhaH03z74tXNNpdLf4UV6otMcHcJtO+X5ATE4TCn9Iw==", + "requires": { + "@ethersproject/bytes": ">=5.0.0-beta.137", + "@ethersproject/constants": ">=5.0.0-beta.133", + "@ethersproject/logger": ">=5.0.0-beta.137" + } + }, "@feathers-plus/batch-loader": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/@feathers-plus/batch-loader/-/batch-loader-0.3.6.tgz", @@ -1898,9 +2006,9 @@ } }, "@fluffy-spoon/substitute": { - "version": "1.139.0", - "resolved": "https://registry.npmjs.org/@fluffy-spoon/substitute/-/substitute-1.139.0.tgz", - "integrity": "sha512-sKx6OWWEkwBrQ5vV1rj4+h/DFcCdIyoppZxF+ox6JDoS3o8ooSld1CdTbcVNIjjwiAcXAAsVXCB/M3zq8bJlfA==", + "version": "1.140.0", + "resolved": "https://registry.npmjs.org/@fluffy-spoon/substitute/-/substitute-1.140.0.tgz", + "integrity": "sha512-t5N+PXMcvaXYhmVTrAx4q0N+H1IZ6Na9OzmHltIlu7thPy7cRVZ2tTWEU8OdJ56Yw2H9S4uIU/7bTybwG3yboQ==", "dev": true }, "@hapi/address": { @@ -2332,9 +2440,9 @@ } }, "@types/bluebird": { - "version": "3.5.31", - "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.31.tgz", - "integrity": "sha512-0PKlnDIxOh3xJHwJpVONR2PP11LhdM+QYiLJGLIbzMqRwLAPxN6lQar2RpdRhfIEh/HjVMgMdhHWJA0CgC5X6w==", + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.32.tgz", + "integrity": "sha512-dIOxFfI0C+jz89g6lQ+TqhGgPQ0MxSnh/E4xuC0blhFtyW269+mPG5QeLgbdwst/LvdP8o1y0o/Gz5EHXLec/g==", "dev": true }, "@types/bn.js": { @@ -2492,9 +2600,9 @@ } }, "@types/lodash": { - "version": "4.14.151", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.151.tgz", - "integrity": "sha512-Zst90IcBX5wnwSu7CAS0vvJkTjTELY4ssKbHiTnGcJgi170uiS8yQDdc3v6S77bRqYQIN1App5a1Pc2lceE5/g==", + "version": "4.14.152", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.152.tgz", + "integrity": "sha512-Vwf9YF2x1GE3WNeUMjT5bTHa2DqgUo87ocdgTScupY2JclZ5Nn7W2RLM/N0+oreexUk8uaVugR81NnTY/jNNXg==", "dev": true }, "@types/mime": { @@ -2515,9 +2623,9 @@ "dev": true }, "@types/node": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.1.tgz", - "integrity": "sha512-FAYBGwC+W6F9+huFIDtn43cpy7+SzG+atzRiTfdp3inUKL2hXnd4rG8hylJLIh4+hqrQy1P17kvJByE/z825hA==" + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.4.tgz", + "integrity": "sha512-k3NqigXWRzQZVBDS5D1U70A5E8Qk4Kh+Ha/x4M8Bt9pF0X05eggfnC9+63Usc9Q928hRUIpIhTQaXsZwZBl4Ew==" }, "@types/node-fetch": { "version": "2.5.7", @@ -2577,9 +2685,9 @@ } }, "@types/sinon": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-9.0.1.tgz", - "integrity": "sha512-vqWk3K1HYJExooYgORUdiGX1EdCWQxPi7P/OEIetdaJn4jNvEYoRRGLG/HwomtbzZ4IP9Syz2k4N50CItv6w6g==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-9.0.3.tgz", + "integrity": "sha512-NWVG++603tEDwmz5k0DwFR1hqP3iBmq5GYi6d+0KCQMQsfDEULF1D7xqZ+iXRJHeGwLVhM+Rv73uzIYuIUVlJQ==", "dev": true, "requires": { "@types/sinonjs__fake-timers": "*" @@ -5136,6 +5244,38 @@ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", "dev": true }, + "cids": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/cids/-/cids-0.7.5.tgz", + "integrity": "sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==", + "requires": { + "buffer": "^5.5.0", + "class-is": "^1.1.0", + "multibase": "~0.6.0", + "multicodec": "^1.0.0", + "multihashes": "~0.4.15" + }, + "dependencies": { + "buffer": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", + "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "multicodec": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-1.0.1.tgz", + "integrity": "sha512-yrrU/K8zHyAH2B0slNVeq3AiwluflHpgQ3TAzwNJcuO2AoPyXgBT2EDkdbP1D8B/yFOY+S2hDYmFlI1vhVFkQw==", + "requires": { + "buffer": "^5.5.0", + "varint": "^5.0.0" + } + } + } + }, "cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", @@ -5145,6 +5285,11 @@ "safe-buffer": "^5.0.1" } }, + "class-is": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz", + "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==" + }, "class-utils": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", @@ -5784,6 +5929,16 @@ "safe-buffer": "5.1.2" } }, + "content-hash": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/content-hash/-/content-hash-2.5.2.tgz", + "integrity": "sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw==", + "requires": { + "cids": "^0.7.1", + "multicodec": "^0.5.5", + "multihashes": "^0.4.15" + } + }, "content-security-policy-builder": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/content-security-policy-builder/-/content-security-policy-builder-2.1.0.tgz", @@ -16274,14 +16429,14 @@ } }, "moment": { - "version": "2.25.3", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.25.3.tgz", - "integrity": "sha512-PuYv0PHxZvzc15Sp8ybUCoQ+xpyPWvjOuK72a5ovzp2LI32rJXOiIfyoFoYvG3s6EwwrdkMyWuRiEHSZRLJNdg==" + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.26.0.tgz", + "integrity": "sha512-oIixUO+OamkUkwjhAVE18rAMfRJNsNe/Stid/gwHSOfHrOtw9EhAY2AHvdKZ/k/MggcYELFCJz/Sn2pL8b8JMw==" }, "moment-timezone": { - "version": "0.5.28", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.28.tgz", - "integrity": "sha512-TDJkZvAyKIVWg5EtVqRzU97w0Rb0YVbfpqyjgu6GwXCAohVRqwZjf4fOzDE6p1Ch98Sro/8hQQi65WDXW5STPw==", + "version": "0.5.31", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.31.tgz", + "integrity": "sha512-+GgHNg8xRhMXfEbv81iDtrVeTcWt0kWmTEY1XQK14dICTXnWJnT0dxdlPspwqF3keKMVPXwayEsk1DI0AA/jdA==", "requires": { "moment": ">= 2.9.0" } @@ -16305,6 +16460,64 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "multibase": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz", + "integrity": "sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==", + "requires": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + }, + "dependencies": { + "buffer": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", + "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + } + } + }, + "multicodec": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-0.5.7.tgz", + "integrity": "sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA==", + "requires": { + "varint": "^5.0.0" + } + }, + "multihashes": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.19.tgz", + "integrity": "sha512-ej74GAfA20imjj00RO5h34aY3pGUFyzn9FJZFWwdeUHlHTkKmv90FrNpvYT4jYf1XXCy5O/5EjVnxTaESgOM6A==", + "requires": { + "buffer": "^5.5.0", + "multibase": "^0.7.0", + "varint": "^5.0.0" + }, + "dependencies": { + "buffer": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", + "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "multibase": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz", + "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==", + "requires": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + } + } + } + }, "mute-stream": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", @@ -18457,6 +18670,14 @@ "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=" }, + "queue": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.1.tgz", + "integrity": "sha512-AJBQabRCCNr9ANq8v77RJEv73DPbn55cdTb+Giq4X0AVnNVZvMHlYp7XlQiN+1npCZj1DuSmaA2hYVUUDgxFDg==", + "requires": { + "inherits": "~2.0.3" + } + }, "quick-lru": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", @@ -19324,9 +19545,9 @@ } }, "sequelize": { - "version": "5.21.9", - "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-5.21.9.tgz", - "integrity": "sha512-CCUgdaGm92ro9ULF3Pi4CLToAYajB3bCAw6mkruAtAsrb/PkK1sl83kLhBiTIxEzTcrtj5Tt/ZqJ8kKE1cRncA==", + "version": "5.21.10", + "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-5.21.10.tgz", + "integrity": "sha512-qni5lKIa4wBdbi3KQYj20R5TC0/a88qi/1XhGDzDvTaWxhx4gEpLr6aGwvfbvVD7XCilvOgjoBkBB0fLVpwNsw==", "requires": { "bluebird": "^3.5.0", "cls-bluebird": "^2.1.0", @@ -19357,6 +19578,14 @@ "resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-2.3.0.tgz", "integrity": "sha512-Ibz08vnXvkZ8LJTiUOxRcj1Ckdn7qafNZ2t59jYHMX1VIebTAOYefWdRYFt6z6+hy52WGthAHAoLc9hvk3onqA==" }, + "sequelize-store": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/sequelize-store/-/sequelize-store-0.3.1.tgz", + "integrity": "sha512-zUe4KHrXsL8h9qKoB1PFiDYIIpiwv0RO2izD6pmxscbVy5ksQhG78El9lOiQPflOPET1qIQE++psyVu3eFtV0Q==", + "requires": { + "queue": "^6.0.1" + } + }, "sequelize-typescript": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/sequelize-typescript/-/sequelize-typescript-1.1.0.tgz", @@ -23526,6 +23755,11 @@ "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=", "dev": true }, + "varint": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.0.tgz", + "integrity": "sha1-2Ca4n3SQcy+rwMDtaT7Uddyynr8=" + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -23974,60 +24208,60 @@ } }, "web3-core-subscriptions": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.2.7.tgz", - "integrity": "sha512-W/CzQYOUawdMDvkgA/fmLsnG5aMpbjrs78LZMbc0MFXLpH3ofqAgO2by4QZrrTShUUTeWS0ZuEkFFL/iFrSObw==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.2.8.tgz", + "integrity": "sha512-wmsRJ4ipwoF1mlOR+Oo8JdKigpkoVNQtqiRUuyQrTVhJx7GBuSaAIenpBYlkucC+RgByoGybR7Q3tTNJ6z/2tQ==", "requires": { "eventemitter3": "3.1.2", "underscore": "1.9.1", - "web3-core-helpers": "1.2.7" + "web3-core-helpers": "1.2.8" }, "dependencies": { "web3-core-helpers": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.2.7.tgz", - "integrity": "sha512-bdU++9QATGeCetVrMp8pV97aQtVkN5oLBf/TWu/qumC6jK/YqrvLlBJLdwbz0QveU8zOSap6GCvJbqKvmmbV2A==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.2.8.tgz", + "integrity": "sha512-Wrl7ZPKn3Xyg0Hl5+shDnJcLP+EtTfThmQ1eCJLcg/BZqvLUR1SkOslNlhEojcYeBwhhymAKs8dfQbtYi+HMnw==", "requires": { "underscore": "1.9.1", - "web3-eth-iban": "1.2.7", - "web3-utils": "1.2.7" + "web3-eth-iban": "1.2.8", + "web3-utils": "1.2.8" } }, "web3-eth-iban": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.2.7.tgz", - "integrity": "sha512-2NrClz1PoQ3nSJBd+91ylCOVga9qbTxjRofq/oSCoHVAEvz3WZyttx9k5DC+0rWqwJF1h69ufFvdHAAlmN/4lg==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.2.8.tgz", + "integrity": "sha512-xgPUOuDOQJYloUS334/wot6jvp6K8JBz8UvQ1tAxU9LO2v2DW+IDTJ5gQ6TdutTmzdDi97KdwhwnQwhQh5Z1PA==", "requires": { "bn.js": "4.11.8", - "web3-utils": "1.2.7" + "web3-utils": "1.2.8" } } } }, "web3-eth": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.2.7.tgz", - "integrity": "sha512-ljLd0oB4IjWkzFGVan4HkYhJXhSXgn9iaSaxdJixKGntZPgWMJfxeA+uLwTrlxrWzhvy4f+39WnT7wCh5e9TGg==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.2.8.tgz", + "integrity": "sha512-CEnVIIR1zZQ9vQh/kPFAUbvbbHYkC84y15jdhRUDDGR6bs4FxO2NNWR2YDtNe038lrz747tZahsC9kEiGkJFZQ==", "requires": { "underscore": "1.9.1", - "web3-core": "1.2.7", - "web3-core-helpers": "1.2.7", - "web3-core-method": "1.2.7", - "web3-core-subscriptions": "1.2.7", - "web3-eth-abi": "1.2.7", - "web3-eth-accounts": "1.2.7", - "web3-eth-contract": "1.2.7", - "web3-eth-ens": "1.2.7", - "web3-eth-iban": "1.2.7", - "web3-eth-personal": "1.2.7", - "web3-net": "1.2.7", - "web3-utils": "1.2.7" + "web3-core": "1.2.8", + "web3-core-helpers": "1.2.8", + "web3-core-method": "1.2.8", + "web3-core-subscriptions": "1.2.8", + "web3-eth-abi": "1.2.8", + "web3-eth-accounts": "1.2.8", + "web3-eth-contract": "1.2.8", + "web3-eth-ens": "1.2.8", + "web3-eth-iban": "1.2.8", + "web3-eth-personal": "1.2.8", + "web3-net": "1.2.8", + "web3-utils": "1.2.8" }, "dependencies": { "@types/node": { - "version": "12.12.37", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.37.tgz", - "integrity": "sha512-4mXKoDptrXAwZErQHrLzpe0FN/0Wmf5JRniSVIdwUrtDf9wnmEV1teCNLBo/TwuXhkK/bVegoEn/wmb+x0AuPg==" + "version": "12.12.41", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.41.tgz", + "integrity": "sha512-Q+eSkdYQJ2XK1AJnr4Ji8Gvk3sRDybEwfTvtL9CA25FFUSD2EgZQewN6VCyWYZCXg5MWZdwogdTNBhlWRcWS1w==" }, "eth-lib": { "version": "0.2.8", @@ -24054,75 +24288,75 @@ "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" }, "web3-core": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.2.7.tgz", - "integrity": "sha512-QA0MTae0gXcr3KHe3cQ4x56+Wh43ZKWfMwg1gfCc3NNxPRM1jJ8qudzyptCAUcxUGXWpDG8syLIn1APDz5J8BQ==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.2.8.tgz", + "integrity": "sha512-hvlYWyE1UcLoGa6qF1GoxGgi1quFsZOdwIUIVsAp+sp0plXp/Nqva2lAjJ+FFyWtVKbC7Zq+qwTJ4iP1aN0vTg==", "requires": { "@types/bn.js": "^4.11.4", "@types/node": "^12.6.1", "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.2.7", - "web3-core-method": "1.2.7", - "web3-core-requestmanager": "1.2.7", - "web3-utils": "1.2.7" + "web3-core-helpers": "1.2.8", + "web3-core-method": "1.2.8", + "web3-core-requestmanager": "1.2.8", + "web3-utils": "1.2.8" } }, "web3-core-helpers": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.2.7.tgz", - "integrity": "sha512-bdU++9QATGeCetVrMp8pV97aQtVkN5oLBf/TWu/qumC6jK/YqrvLlBJLdwbz0QveU8zOSap6GCvJbqKvmmbV2A==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.2.8.tgz", + "integrity": "sha512-Wrl7ZPKn3Xyg0Hl5+shDnJcLP+EtTfThmQ1eCJLcg/BZqvLUR1SkOslNlhEojcYeBwhhymAKs8dfQbtYi+HMnw==", "requires": { "underscore": "1.9.1", - "web3-eth-iban": "1.2.7", - "web3-utils": "1.2.7" + "web3-eth-iban": "1.2.8", + "web3-utils": "1.2.8" } }, "web3-core-method": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.2.7.tgz", - "integrity": "sha512-e1TI0QUnByDMbQ8QHwnjxfjKw0LIgVRY4TYrlPijET9ebqUJU1HCayn/BHIMpV6LKyR1fQj9EldWyT64wZQXkg==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.2.8.tgz", + "integrity": "sha512-69qbvOgx0Frw46dXvEKzYgtaPXpUaQAlQmczgb0ZUBHsEU2K7jTtFgBy6kVBgAwsXDvoZ99AX4SjpY2dTMwPkw==", "requires": { "underscore": "1.9.1", - "web3-core-helpers": "1.2.7", - "web3-core-promievent": "1.2.7", - "web3-core-subscriptions": "1.2.7", - "web3-utils": "1.2.7" + "web3-core-helpers": "1.2.8", + "web3-core-promievent": "1.2.8", + "web3-core-subscriptions": "1.2.8", + "web3-utils": "1.2.8" } }, "web3-core-promievent": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.2.7.tgz", - "integrity": "sha512-jNmsM/czCeMGQqKKwM9/HZVTJVIF96hdMVNN/V9TGvp+EEE7vDhB4pUocDnc/QF9Z/5QFBCVmvNWttlRgZmU0A==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.2.8.tgz", + "integrity": "sha512-3EdRieaHpBVVhfGjoREQfdoCM3xC0WwWjXXzT6oTldotfYC38kwk/GW8c8txYiLP/KxhslAN1cJSlXNOJjKSog==", "requires": { "eventemitter3": "3.1.2" } }, "web3-core-requestmanager": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.2.7.tgz", - "integrity": "sha512-HJb/txjHixu1dxIebiZQKBoJCaNu4gsh7mq/uj6Z/w6tIHbybL90s/7ADyMED353yyJ2tDWtYJqeMVAR+KtdaA==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.2.8.tgz", + "integrity": "sha512-bwc2ABG6yzgTy28fv4t59g+tf6+UmTRMoF8HqTeiNDffoMKP2akyKFZeu1oD2gE7j/7GA75TAUjwJ7pH9ek1MA==", "requires": { "underscore": "1.9.1", - "web3-core-helpers": "1.2.7", - "web3-providers-http": "1.2.7", - "web3-providers-ipc": "1.2.7", - "web3-providers-ws": "1.2.7" + "web3-core-helpers": "1.2.8", + "web3-providers-http": "1.2.8", + "web3-providers-ipc": "1.2.8", + "web3-providers-ws": "1.2.8" } }, "web3-eth-abi": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.2.7.tgz", - "integrity": "sha512-4FnlT1q+D0XBkxSMXlIb/eG337uQeMaUdtVQ4PZ3XzxqpcoDuMgXm4o+3NRxnWmr4AMm6QKjM+hcC7c0mBKcyg==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.2.8.tgz", + "integrity": "sha512-OKp/maLdKHPpQxZhEd0HgnCJFQajsGe42WOG6SVftlgzyR8Jjv4KNm46TKvb3hv5OJTKZWU7nZIxkEG+fyI58w==", "requires": { - "ethers": "4.0.0-beta.3", + "@ethersproject/abi": "5.0.0-beta.153", "underscore": "1.9.1", - "web3-utils": "1.2.7" + "web3-utils": "1.2.8" } }, "web3-eth-accounts": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.2.7.tgz", - "integrity": "sha512-AE7QWi/iIQIjXwlAPtlMabm/OPFF0a1PhxT1EiTckpYNP8fYs6jW7lYxEtJPPJIKqfMjoi1xkEqTVR1YZQ88lg==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.2.8.tgz", + "integrity": "sha512-QODqSD4SZN/1oWfvlvsuum6Ud9+2FUTW4VTPJh245YTewCpa0M5+Fzug3UTeUZNv88STwC//dV72zReITNh4ZQ==", "requires": { "@web3-js/scrypt-shim": "^0.1.0", "crypto-browserify": "3.12.0", @@ -24131,93 +24365,94 @@ "ethereumjs-tx": "^2.1.1", "underscore": "1.9.1", "uuid": "3.3.2", - "web3-core": "1.2.7", - "web3-core-helpers": "1.2.7", - "web3-core-method": "1.2.7", - "web3-utils": "1.2.7" + "web3-core": "1.2.8", + "web3-core-helpers": "1.2.8", + "web3-core-method": "1.2.8", + "web3-utils": "1.2.8" } }, "web3-eth-ens": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.2.7.tgz", - "integrity": "sha512-SPRnvUNWQ0CnnTDBteGIJkvFWEizJcAHlVsrFLICwcwFZu+appjX1UOaoGu2h3GXWtc/XZlu7B451Gi+Os2cTg==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.2.8.tgz", + "integrity": "sha512-zsFXY26BMGkihPkEO5qj9AEqyxPH4mclbzYs1dyrw7sHFmrUvhZc+jLGT9WyQGoujq37RN2l/tlOpCaFVVR8ng==", "requires": { + "content-hash": "^2.5.2", "eth-ens-namehash": "2.0.8", "underscore": "1.9.1", - "web3-core": "1.2.7", - "web3-core-helpers": "1.2.7", - "web3-core-promievent": "1.2.7", - "web3-eth-abi": "1.2.7", - "web3-eth-contract": "1.2.7", - "web3-utils": "1.2.7" + "web3-core": "1.2.8", + "web3-core-helpers": "1.2.8", + "web3-core-promievent": "1.2.8", + "web3-eth-abi": "1.2.8", + "web3-eth-contract": "1.2.8", + "web3-utils": "1.2.8" } }, "web3-eth-iban": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.2.7.tgz", - "integrity": "sha512-2NrClz1PoQ3nSJBd+91ylCOVga9qbTxjRofq/oSCoHVAEvz3WZyttx9k5DC+0rWqwJF1h69ufFvdHAAlmN/4lg==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.2.8.tgz", + "integrity": "sha512-xgPUOuDOQJYloUS334/wot6jvp6K8JBz8UvQ1tAxU9LO2v2DW+IDTJ5gQ6TdutTmzdDi97KdwhwnQwhQh5Z1PA==", "requires": { "bn.js": "4.11.8", - "web3-utils": "1.2.7" + "web3-utils": "1.2.8" } }, "web3-eth-personal": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.2.7.tgz", - "integrity": "sha512-2OAa1Spz0uB29dwCM8+1y0So7E47A4gKznjBEwXIYEcUIsvwT5X7ofFhC2XxyRpqlIWZSQAxRSSJFyupRRXzyw==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.2.8.tgz", + "integrity": "sha512-sWhxF1cpF9pB1wMISrOSy/i8IB1NWtvoXT9dfkWtvByGf3JfC2DlnllLaA1f9ohyvxnR+QTgPKgOQDknmqDstw==", "requires": { "@types/node": "^12.6.1", - "web3-core": "1.2.7", - "web3-core-helpers": "1.2.7", - "web3-core-method": "1.2.7", - "web3-net": "1.2.7", - "web3-utils": "1.2.7" + "web3-core": "1.2.8", + "web3-core-helpers": "1.2.8", + "web3-core-method": "1.2.8", + "web3-net": "1.2.8", + "web3-utils": "1.2.8" } }, "web3-net": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.2.7.tgz", - "integrity": "sha512-j9qeZrS1FNyCeA0BfdLojkxOZQz3FKa1DJI+Dw9fEVhZS68vLOFANu2RB96gR9BoPHo5+k5D3NsKOoxt1gw3Gg==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.2.8.tgz", + "integrity": "sha512-Nsq6qgncvvThOjC+sQ+NfDH8L7jclQCFzLFYa9wsd5J6HJ6f5gJl/mv6rsZQX9iDEYDPKkDfyqHktynOBgKWMQ==", "requires": { - "web3-core": "1.2.7", - "web3-core-method": "1.2.7", - "web3-utils": "1.2.7" + "web3-core": "1.2.8", + "web3-core-method": "1.2.8", + "web3-utils": "1.2.8" } }, "web3-providers-http": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.2.7.tgz", - "integrity": "sha512-vazGx5onuH/zogrwkUaLFJwFcJ6CckP65VFSHoiV+GTQdkOqgoDIha7StKkslvDz4XJ2FuY/zOZHbtuOYeltXQ==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.2.8.tgz", + "integrity": "sha512-Esj4SpgabmBDOR4QD3qYapzwFYWHigcdgdjvt/VWT5/7TD10o52hr+Nsvp3/XV5AFrcCMdY+lzKFLVH24u0sww==", "requires": { - "web3-core-helpers": "1.2.7", + "web3-core-helpers": "1.2.8", "xhr2-cookies": "1.1.0" } }, "web3-providers-ipc": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.2.7.tgz", - "integrity": "sha512-/zc0y724H2zbkV4UbGGMhsEiLfafjagIzfrsWZnyTZUlSB0OGRmmFm2EkLJAgtXrLiodaHHyXKM0vB8S24bxdA==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.2.8.tgz", + "integrity": "sha512-ts3/UXCTRADPASdJ27vBVmcfM+lfG9QVBxGedY6+oNIo5EPxBUtsz94R32sfvFd6ofPsz6gOhK/M/ZKiJoi1sg==", "requires": { "oboe": "2.1.4", "underscore": "1.9.1", - "web3-core-helpers": "1.2.7" + "web3-core-helpers": "1.2.8" } }, "web3-providers-ws": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.2.7.tgz", - "integrity": "sha512-b5XzqDpRkNVe6MFs5K6iqOEyjQikHtg3KuU2/ClCDV37hm0WN4xCRVMC0LwegulbDXZej3zT9+1CYzGaGFREzA==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.2.8.tgz", + "integrity": "sha512-Gcm0n82wd/XVeGFGTx+v56UqyrV9EyB2r1QFaBx4mS+VHbW2MCOdiRbNDfoZQslflnCWl8oHsivJ8Tya9kqlTQ==", "requires": { "@web3-js/websocket": "^1.0.29", "eventemitter3": "^4.0.0", "underscore": "1.9.1", - "web3-core-helpers": "1.2.7" + "web3-core-helpers": "1.2.8" }, "dependencies": { "eventemitter3": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz", - "integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==" + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", + "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==" } } } @@ -24299,135 +24534,135 @@ } }, "web3-eth-contract": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.2.7.tgz", - "integrity": "sha512-uW23Y0iL7XroRNbf9fWZ1N6OYhEYTJX8gTuYASuRnpYrISN5QGiQML6pq/NCzqypR1bl5E0fuINZQSK/xefIVw==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.2.8.tgz", + "integrity": "sha512-EWRLVhZksbzGAyHd7RaOsakjCJBA2BREWiJmBDlrxDBqw8HltXFzKdkRug/mwVNa5ZYMabKSRF/MMh0Sx06CFw==", "requires": { "@types/bn.js": "^4.11.4", "underscore": "1.9.1", - "web3-core": "1.2.7", - "web3-core-helpers": "1.2.7", - "web3-core-method": "1.2.7", - "web3-core-promievent": "1.2.7", - "web3-core-subscriptions": "1.2.7", - "web3-eth-abi": "1.2.7", - "web3-utils": "1.2.7" + "web3-core": "1.2.8", + "web3-core-helpers": "1.2.8", + "web3-core-method": "1.2.8", + "web3-core-promievent": "1.2.8", + "web3-core-subscriptions": "1.2.8", + "web3-eth-abi": "1.2.8", + "web3-utils": "1.2.8" }, "dependencies": { "@types/node": { - "version": "12.12.37", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.37.tgz", - "integrity": "sha512-4mXKoDptrXAwZErQHrLzpe0FN/0Wmf5JRniSVIdwUrtDf9wnmEV1teCNLBo/TwuXhkK/bVegoEn/wmb+x0AuPg==" + "version": "12.12.41", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.41.tgz", + "integrity": "sha512-Q+eSkdYQJ2XK1AJnr4Ji8Gvk3sRDybEwfTvtL9CA25FFUSD2EgZQewN6VCyWYZCXg5MWZdwogdTNBhlWRcWS1w==" }, "web3-core": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.2.7.tgz", - "integrity": "sha512-QA0MTae0gXcr3KHe3cQ4x56+Wh43ZKWfMwg1gfCc3NNxPRM1jJ8qudzyptCAUcxUGXWpDG8syLIn1APDz5J8BQ==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.2.8.tgz", + "integrity": "sha512-hvlYWyE1UcLoGa6qF1GoxGgi1quFsZOdwIUIVsAp+sp0plXp/Nqva2lAjJ+FFyWtVKbC7Zq+qwTJ4iP1aN0vTg==", "requires": { "@types/bn.js": "^4.11.4", "@types/node": "^12.6.1", "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.2.7", - "web3-core-method": "1.2.7", - "web3-core-requestmanager": "1.2.7", - "web3-utils": "1.2.7" + "web3-core-helpers": "1.2.8", + "web3-core-method": "1.2.8", + "web3-core-requestmanager": "1.2.8", + "web3-utils": "1.2.8" } }, "web3-core-helpers": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.2.7.tgz", - "integrity": "sha512-bdU++9QATGeCetVrMp8pV97aQtVkN5oLBf/TWu/qumC6jK/YqrvLlBJLdwbz0QveU8zOSap6GCvJbqKvmmbV2A==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.2.8.tgz", + "integrity": "sha512-Wrl7ZPKn3Xyg0Hl5+shDnJcLP+EtTfThmQ1eCJLcg/BZqvLUR1SkOslNlhEojcYeBwhhymAKs8dfQbtYi+HMnw==", "requires": { "underscore": "1.9.1", - "web3-eth-iban": "1.2.7", - "web3-utils": "1.2.7" + "web3-eth-iban": "1.2.8", + "web3-utils": "1.2.8" } }, "web3-core-method": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.2.7.tgz", - "integrity": "sha512-e1TI0QUnByDMbQ8QHwnjxfjKw0LIgVRY4TYrlPijET9ebqUJU1HCayn/BHIMpV6LKyR1fQj9EldWyT64wZQXkg==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.2.8.tgz", + "integrity": "sha512-69qbvOgx0Frw46dXvEKzYgtaPXpUaQAlQmczgb0ZUBHsEU2K7jTtFgBy6kVBgAwsXDvoZ99AX4SjpY2dTMwPkw==", "requires": { "underscore": "1.9.1", - "web3-core-helpers": "1.2.7", - "web3-core-promievent": "1.2.7", - "web3-core-subscriptions": "1.2.7", - "web3-utils": "1.2.7" + "web3-core-helpers": "1.2.8", + "web3-core-promievent": "1.2.8", + "web3-core-subscriptions": "1.2.8", + "web3-utils": "1.2.8" } }, "web3-core-promievent": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.2.7.tgz", - "integrity": "sha512-jNmsM/czCeMGQqKKwM9/HZVTJVIF96hdMVNN/V9TGvp+EEE7vDhB4pUocDnc/QF9Z/5QFBCVmvNWttlRgZmU0A==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.2.8.tgz", + "integrity": "sha512-3EdRieaHpBVVhfGjoREQfdoCM3xC0WwWjXXzT6oTldotfYC38kwk/GW8c8txYiLP/KxhslAN1cJSlXNOJjKSog==", "requires": { "eventemitter3": "3.1.2" } }, "web3-core-requestmanager": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.2.7.tgz", - "integrity": "sha512-HJb/txjHixu1dxIebiZQKBoJCaNu4gsh7mq/uj6Z/w6tIHbybL90s/7ADyMED353yyJ2tDWtYJqeMVAR+KtdaA==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.2.8.tgz", + "integrity": "sha512-bwc2ABG6yzgTy28fv4t59g+tf6+UmTRMoF8HqTeiNDffoMKP2akyKFZeu1oD2gE7j/7GA75TAUjwJ7pH9ek1MA==", "requires": { "underscore": "1.9.1", - "web3-core-helpers": "1.2.7", - "web3-providers-http": "1.2.7", - "web3-providers-ipc": "1.2.7", - "web3-providers-ws": "1.2.7" + "web3-core-helpers": "1.2.8", + "web3-providers-http": "1.2.8", + "web3-providers-ipc": "1.2.8", + "web3-providers-ws": "1.2.8" } }, "web3-eth-abi": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.2.7.tgz", - "integrity": "sha512-4FnlT1q+D0XBkxSMXlIb/eG337uQeMaUdtVQ4PZ3XzxqpcoDuMgXm4o+3NRxnWmr4AMm6QKjM+hcC7c0mBKcyg==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.2.8.tgz", + "integrity": "sha512-OKp/maLdKHPpQxZhEd0HgnCJFQajsGe42WOG6SVftlgzyR8Jjv4KNm46TKvb3hv5OJTKZWU7nZIxkEG+fyI58w==", "requires": { - "ethers": "4.0.0-beta.3", + "@ethersproject/abi": "5.0.0-beta.153", "underscore": "1.9.1", - "web3-utils": "1.2.7" + "web3-utils": "1.2.8" } }, "web3-eth-iban": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.2.7.tgz", - "integrity": "sha512-2NrClz1PoQ3nSJBd+91ylCOVga9qbTxjRofq/oSCoHVAEvz3WZyttx9k5DC+0rWqwJF1h69ufFvdHAAlmN/4lg==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.2.8.tgz", + "integrity": "sha512-xgPUOuDOQJYloUS334/wot6jvp6K8JBz8UvQ1tAxU9LO2v2DW+IDTJ5gQ6TdutTmzdDi97KdwhwnQwhQh5Z1PA==", "requires": { "bn.js": "4.11.8", - "web3-utils": "1.2.7" + "web3-utils": "1.2.8" } }, "web3-providers-http": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.2.7.tgz", - "integrity": "sha512-vazGx5onuH/zogrwkUaLFJwFcJ6CckP65VFSHoiV+GTQdkOqgoDIha7StKkslvDz4XJ2FuY/zOZHbtuOYeltXQ==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.2.8.tgz", + "integrity": "sha512-Esj4SpgabmBDOR4QD3qYapzwFYWHigcdgdjvt/VWT5/7TD10o52hr+Nsvp3/XV5AFrcCMdY+lzKFLVH24u0sww==", "requires": { - "web3-core-helpers": "1.2.7", + "web3-core-helpers": "1.2.8", "xhr2-cookies": "1.1.0" } }, "web3-providers-ipc": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.2.7.tgz", - "integrity": "sha512-/zc0y724H2zbkV4UbGGMhsEiLfafjagIzfrsWZnyTZUlSB0OGRmmFm2EkLJAgtXrLiodaHHyXKM0vB8S24bxdA==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.2.8.tgz", + "integrity": "sha512-ts3/UXCTRADPASdJ27vBVmcfM+lfG9QVBxGedY6+oNIo5EPxBUtsz94R32sfvFd6ofPsz6gOhK/M/ZKiJoi1sg==", "requires": { "oboe": "2.1.4", "underscore": "1.9.1", - "web3-core-helpers": "1.2.7" + "web3-core-helpers": "1.2.8" } }, "web3-providers-ws": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.2.7.tgz", - "integrity": "sha512-b5XzqDpRkNVe6MFs5K6iqOEyjQikHtg3KuU2/ClCDV37hm0WN4xCRVMC0LwegulbDXZej3zT9+1CYzGaGFREzA==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.2.8.tgz", + "integrity": "sha512-Gcm0n82wd/XVeGFGTx+v56UqyrV9EyB2r1QFaBx4mS+VHbW2MCOdiRbNDfoZQslflnCWl8oHsivJ8Tya9kqlTQ==", "requires": { "@web3-js/websocket": "^1.0.29", "eventemitter3": "^4.0.0", "underscore": "1.9.1", - "web3-core-helpers": "1.2.7" + "web3-core-helpers": "1.2.8" }, "dependencies": { "eventemitter3": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz", - "integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==" + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", + "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==" } } } @@ -24671,9 +24906,9 @@ } }, "web3-utils": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.7.tgz", - "integrity": "sha512-FBh/CPJND+eiPeUF9KVbTyTZtXNWxPWtByBaWS6e2x4ACazPX711EeNaZaChIOGSLGe6se2n7kg6wnawe/MjuQ==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.8.tgz", + "integrity": "sha512-9SIVGFLajwlmo5joC4DGxuy2OeDkRCXVWT8JWcDQ+BayNVHyAWGvn0oGkQ0ys14Un0KK6bjjKoD0xYs4k+FaVw==", "requires": { "bn.js": "4.11.8", "eth-lib": "0.2.7", diff --git a/package.json b/package.json index f92167a7..2353d11b 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "@oclif/command": "^1.5.19", "@oclif/config": "^1.14.0", "@oclif/errors": "^1.2.2", - "@oclif/parser": "^3.8.4", + "@oclif/parser": "^3.8.5", "@oclif/plugin-help": "^3.0.1", "@rsksmart/rif-marketplace-nfts": "~0.0.2", "@rsksmart/rif-marketplace-storage": "^0.1.0-dev.0", @@ -67,32 +67,32 @@ "coingecko-api": "^1.0.10", "colors": "^1.4.0", "compression": "^1.7.4", - "conf": "^6.2.4", "config": "^3.3.1", "cors": "^2.8.5", "feathers-hooks-common": "^5.0.3", "feathers-sequelize": "^6.1.0", "helmet": "^3.22.0", "listr": "^0.14.3", - "pg": "^8.0.3", + "pg": "^8.2.1", "pg-hstore": "^2.3.3", "reflect-metadata": "^0.1.13", - "sequelize": "^5.21.7", + "sequelize": "^5.21.10", + "sequelize-store": "^0.3.1", "sequelize-typescript": "^1.1.0", "sql-formatter": "^2.3.3", "sqlite3": "^4.2.0", - "web3-core-subscriptions": "^1.2.6", - "web3-eth": "^1.2.6", - "web3-eth-contract": "^1.2.6", - "web3-utils": "^1.2.6", + "web3-core-subscriptions": "^1.2.8", + "web3-eth": "^1.2.8", + "web3-eth-contract": "^1.2.8", + "web3-utils": "^1.2.8", "winston": "^3.2.1", "winston-transport": "^4.3.0" }, "devDependencies": { - "@fluffy-spoon/substitute": "^1.133.0", + "@fluffy-spoon/substitute": "^1.140.0", "@oclif/dev-cli": "^1.22.2", - "@oclif/test": "^1.2.5", - "@types/bluebird": "^3.5.29", + "@oclif/test": "^1.2.6", + "@types/bluebird": "^3.5.32", "@types/chai": "^4.2.11", "@types/chai-as-promised": "^7.1.2", "@types/compression": "^1.0.1", @@ -103,10 +103,10 @@ "@types/helmet": "0.0.47", "@types/listr": "^0.14.2", "@types/mocha": "^7.0.2", - "@types/node": "^14.0.1", + "@types/node": "^14.0.4", "@types/node-fetch": "^2.5.7", "@types/serve-favicon": "^2.5.0", - "@types/sinon": "^9.0.0", + "@types/sinon": "^9.0.3", "@types/sql-formatter": "^2.3.0", "@types/validator": "^13.0.0", "bignumber.js": "^9.0.0", diff --git a/src/app.ts b/src/app.ts index d183b48c..0eada851 100644 --- a/src/app.ts +++ b/src/app.ts @@ -10,7 +10,7 @@ import { Application } from './definitions' import { loggingFactory } from './logger' import sequelize from './sequelize' import blockchain from './blockchain' -import { configure as confConfigure } from './conf' +import { configureStore } from './store' import storage from './storage' import rates from './rates' @@ -51,7 +51,7 @@ export function appFactory (): Application { // Custom general services app.configure(sequelize) app.configure(blockchain) - app.configure(confConfigure) + app.configure(configureStore) /**********************************************************/ // Configure each services diff --git a/src/blockchain/events.ts b/src/blockchain/events.ts index 4eb07775..cc456435 100644 --- a/src/blockchain/events.ts +++ b/src/blockchain/events.ts @@ -5,12 +5,12 @@ import { EventEmitter } from 'events' import { NotImplemented } from '@feathersjs/errors' import { Op } from 'sequelize' import { Sema } from 'async-sema' +import { getObject as getStore } from 'sequelize-store' -import { asyncFilter, scopeStore } from '../utils' -import { confFactory } from '../conf' +import { asyncFilter } from '../utils' import { loggingFactory } from '../logger' import Event, { EventInterface } from './event.model' -import { Store, Logger } from '../definitions' +import { Logger } from '../definitions' // Constant number that defines default interval of all polling mechanisms. const DEFAULT_POLLING_INTERVAL = 5000 @@ -24,6 +24,10 @@ export interface PollingOptions { pollingInterval?: number } +export interface BlockTrackerStore { + [PROCESSED_BLOCK_KEY]?: number +} + export enum EventsEmitterStrategy { POLLING = 1, LISTENING, @@ -43,7 +47,7 @@ export interface EventsEmitterOptions { startingBlock?: number | string // Defines BlockTracker or its configuration - blockTracker?: BlockTracker | { store?: Store, keyPrefix?: string } + blockTracker?: BlockTracker | { store?: BlockTrackerStore, keyPrefix?: string } // Defines the NewBlockEmitter or its configuration newBlockEmitter?: EventEmitter | PollingOptions @@ -57,21 +61,18 @@ export interface EventsEmitterOptions { * of the server. */ export class BlockTracker { - private store: Store - private lastProcessedBlock: number + private readonly store: BlockTrackerStore - constructor (store: Store) { + constructor (store: BlockTrackerStore) { this.store = store - this.lastProcessedBlock = this.store.get(PROCESSED_BLOCK_KEY) } setLastProcessedBlock (block: number): void { - this.lastProcessedBlock = block - this.store.set(PROCESSED_BLOCK_KEY, block) + this.store[PROCESSED_BLOCK_KEY] = block } getLastProcessedBlock (): number | undefined { - return this.lastProcessedBlock + return this.store[PROCESSED_BLOCK_KEY] } } @@ -225,16 +226,11 @@ export abstract class BaseEventsEmitter extends AutoStartStopEventEmitter { if (options.blockTracker instanceof BlockTracker) { this.blockTracker = options.blockTracker } else { - let confStore = options.blockTracker.store || confFactory() - - if (options.blockTracker.keyPrefix) { - confStore = scopeStore(confStore, options.blockTracker.keyPrefix) - } - + const confStore = options.blockTracker.store || getStore(options.blockTracker.keyPrefix ? options.blockTracker.keyPrefix : undefined) this.blockTracker = new BlockTracker(confStore) } } else { - this.blockTracker = new BlockTracker(confFactory()) + this.blockTracker = new BlockTracker(getStore()) } if (options?.newBlockEmitter) { diff --git a/src/blockchain/utils.ts b/src/blockchain/utils.ts index b16d3bcf..af9ed22f 100644 --- a/src/blockchain/utils.ts +++ b/src/blockchain/utils.ts @@ -2,21 +2,14 @@ import { AbiItem } from 'web3-utils' import Eth from 'web3-eth' import { EventEmitter } from 'events' import config from 'config' +import { getObject } from 'sequelize-store' import { loggingFactory } from '../logger' import eventsEmitterFactory, { BlockTracker, EventsEmitterOptions, PollingOptions } from './events' -import { confFactory } from '../conf' -import { scopeStore } from '../utils' -import { Store } from '../definitions' function getBlockTracker (keyPrefix?: string): BlockTracker { - let confStore: Store = confFactory() - - if (keyPrefix) { - confStore = scopeStore(confStore, keyPrefix) - } - - return new BlockTracker(confStore) + const store = getObject(keyPrefix) + return new BlockTracker(store) } export async function getBlockDate (eth: Eth, blockNumber: number): Promise { @@ -24,7 +17,7 @@ export async function getBlockDate (eth: Eth, blockNumber: number): Promise { diff --git a/src/cli/purge.ts b/src/cli/purge.ts index 490491bc..63c2fbd1 100644 --- a/src/cli/purge.ts +++ b/src/cli/purge.ts @@ -3,6 +3,7 @@ import Listr from 'listr' import { sequelizeFactory } from '../sequelize' import { BaseCLICommand, capitalizeFirstLetter, validateServices } from '../utils' import Event from '../blockchain/event.model' +import { initStore } from '../store' export default class Purge extends BaseCLICommand { static get description () { @@ -37,7 +38,10 @@ ${formattedServices}` } // Init database connection - sequelizeFactory() + const sequelize = sequelizeFactory() + + // Init Store + await initStore(sequelize) const tasksDefinition = servicesToPurge.map( serviceName => { diff --git a/src/conf.ts b/src/conf.ts deleted file mode 100644 index 7f9d513a..00000000 --- a/src/conf.ts +++ /dev/null @@ -1,31 +0,0 @@ -import config from 'config' -import Conf from 'conf' -import { loggingFactory as logFactory } from './logger' - -const logger = logFactory('conf') - -export interface ConfOptions { - storage: { - lastProcessedBlock: number - } - rates: { - lastUpdate: number - } - rns: { - lastProcessedBlock: number - } -} - -export function confFactory (): Conf { - const configName = config.get('conf.name') - - return new Conf({ configName }) -} - -export function configure (): void { - if (!config.get('conf.persist')) { - logger.info('Clearing all persisted configuration.') - - confFactory().clear() - } -} diff --git a/src/definitions.ts b/src/definitions.ts index 3c92ed0b..db3c51cc 100644 --- a/src/definitions.ts +++ b/src/definitions.ts @@ -20,11 +20,6 @@ interface ServiceTypes { // The application instance type that will be used everywhere else export type Application = ExpressFeathers; -export interface Store { - get (key: string): any - set (key: string, value: any): void -} - export interface CachedService { precache (eth?: Eth): Promise purge (): Promise @@ -95,14 +90,6 @@ export interface Config { path?: string } - conf?: { - // Name for config to have separate configs for different environments (test, dev, prod) - name?: string - - // Specifies if configuration using Conf() should be persisted between restarts - persist?: boolean - } - blockchain?: { // Address to where web3js should connect to. Should be WS endpoint. provider?: string diff --git a/src/rates/providers/coingecko.ts b/src/rates/providers/coingecko.ts index b865425d..ba59bcfd 100644 --- a/src/rates/providers/coingecko.ts +++ b/src/rates/providers/coingecko.ts @@ -1,7 +1,6 @@ -import { FetchedRates, ToSymbols, FromSymbols, SupportedToSymbols, SupportedFromSymbols } from '../../definitions' +import { FetchedRates, ToSymbols, FromSymbols } from '../../definitions' import CoinGecko from 'coingecko-api' -import { ConfigurationError, RatesProviderError } from '../../errors' -import config from 'config' +import { RatesProviderError } from '../../errors' const SUPPORTED_FROM_SYMBOLS: Record = { rbtc: 'rootstock', diff --git a/src/rns/index.ts b/src/rns/index.ts index 7e6ef3cb..6f4eeade 100644 --- a/src/rns/index.ts +++ b/src/rns/index.ts @@ -3,10 +3,10 @@ import Eth from 'web3-eth' import { AbiItem } from 'web3-utils' import config from 'config' import { EventData } from 'web3-eth-contract' +import { getObject } from 'sequelize-store' import { Application, CachedService } from '../definitions' import { loggingFactory } from '../logger' -import { confFactory } from '../conf' import { ethFactory } from '../blockchain' import { getEventsEmitterForService, isServiceInitialized } from '../blockchain/utils' @@ -22,7 +22,7 @@ import rnsContractAbi from '@rsksmart/rns-rskregistrar/RSKOwnerData.json' import rnsReverseContractAbi from '@rsksmart/rns-reverse/NameResolverData.json' import auctionRegistrarContractAbi from '@rsksmart/rns-auction-registrar/TokenRegistrarData.json' import simplePlacementsContractAbi from '@rsksmart/rif-marketplace-nfts/ERC721SimplePlacementsABI.json' -import { errorHandler } from '../utils' +import { errorHandler, waitForReadyApp } from '../utils' import { processRskOwner, processAuctionRegistrar } from './rns.precache' @@ -83,6 +83,8 @@ const rns: CachedService = { } logger.info('RNS service: enabled') + await waitForReadyApp(app) + // Initialize feather's service app.use('/rns/v0/:ownerAddress/domains', new RnsService({ Model: Domain })) app.use('/rns/v0/:ownerAddress/sold', new RnsService({ Model: SoldDomain })) @@ -139,9 +141,10 @@ const rns: CachedService = { const domainsCount = await Domain.destroy({ where: {}, truncate: true, cascade: true }) logger.info(`Removed ${offersCount} offers entries, ${soldCount} sold domains and ${domainsCount} domains`) - confFactory().delete('rns.owner') - confFactory().delete('rns.reverse') - confFactory().delete('rns.placement') + const store = getObject() + delete store['rns.placement.lastProcessedBlock'] + delete store['rns.reverse.lastProcessedBlock'] + delete store['rns.owner.lastProcessedBlock'] } } diff --git a/src/rns/rns.precache.ts b/src/rns/rns.precache.ts index 7a335d18..b22fe95e 100644 --- a/src/rns/rns.precache.ts +++ b/src/rns/rns.precache.ts @@ -2,7 +2,7 @@ import { Eth } from 'web3-eth' import config from 'config' import Utils from 'web3-utils' import abiDecoder from 'abi-decoder' -import { BlockchainServiceOptions, Logger } from '../definitions' +import { Logger } from '../definitions' import Domain from './models/domain.model' @@ -37,9 +37,14 @@ abiDecoder.addABI([ ]) export async function processRskOwner (eth: Eth, logger: Logger, contractAbi: Utils.AbiItem[]) { + if (!config.has('rns.fifsAddrRegistrar.contractAddress')) { + logger.warn('RNS FIFS Registrar address is not defined, skipping Auction Registrar precaching!') + return + } + logger.info('Processing events Transfer from FIFSAddrRegistrar') const rskOwner = new eth.Contract(contractAbi, config.get('rns.owner.contractAddress')) - const startingBlock = config.get('rns.owner')?.eventsEmitter?.startingBlock || 'genesis' + const startingBlock = config.get('rns.owner.eventsEmitter.startingBlock') const rskOwnerEvents = await rskOwner.getPastEvents('Transfer', { filter: { from: config.get('rns.fifsAddrRegistrar.contractAddress') }, fromBlock: startingBlock @@ -60,8 +65,13 @@ export async function processRskOwner (eth: Eth, logger: Logger, contractAbi: Ut } export async function processAuctionRegistrar (eth: Eth, logger: Logger, contractAbi: Utils.AbiItem[]) { + if (!config.has('rns.registrar.contractAddress')) { + logger.warn('RNS Registrar address is not defined, skipping Auction Registrar precaching!') + return + } + logger.info('Processing events HashRegistered') - const startingBlock = config.get('rns.registrar')?.eventsEmitter?.startingBlock || 'genesis' + const startingBlock = config.get('rns.registrar.startingBlock') const auctionRegistrar = new eth.Contract(contractAbi, config.get('rns.registrar.contractAddress')) const auctionRegistrarEvents = await auctionRegistrar.getPastEvents('HashRegistered', { filter: { from: '0x0000000000000000000000000000000000000000' }, diff --git a/src/storage/index.ts b/src/storage/index.ts index 0952747e..72cc81a3 100644 --- a/src/storage/index.ts +++ b/src/storage/index.ts @@ -3,6 +3,7 @@ import Eth from 'web3-eth' import { AbiItem } from 'web3-utils' import config from 'config' import { EventData } from 'web3-eth-contract' +import { getObject } from 'sequelize-store' import StorageOffer from './models/storage-offer.model' import { Application, CachedService } from '../definitions' @@ -11,9 +12,8 @@ import { getEventsEmitterForService, isServiceInitialized } from '../blockchain/ import hooks from './storage.hooks' import eventProcessor from './storage.processor' import Price from './models/price.model' -import { confFactory } from '../conf' import { ethFactory } from '../blockchain' -import { errorHandler } from '../utils' +import { errorHandler, waitForReadyApp } from '../utils' import storageManagerContract from '@rsksmart/rif-marketplace-storage/build/contracts/StorageManager.json' @@ -60,6 +60,8 @@ const storage: CachedService = { } logger.info('Storage service: enabled') + await waitForReadyApp(app) + // Initialize feather's service app.use('/storage/v0/offers', new StorageOfferService({ Model: StorageOffer })) const service = app.service('/storage/v0/offers') @@ -90,7 +92,8 @@ const storage: CachedService = { const offersCount = await StorageOffer.destroy({ where: {}, truncate: true, cascade: true }) logger.info(`Removed ${priceCount} price entries and ${offersCount} storage offers`) - confFactory().delete(SERVICE_NAME) + const store = getObject() + delete store['storage.lastProcessedBlock'] }, precache diff --git a/src/store.ts b/src/store.ts new file mode 100644 index 00000000..8dc804c6 --- /dev/null +++ b/src/store.ts @@ -0,0 +1,17 @@ +import { init } from 'sequelize-store' +import { Application } from './definitions' +import type { Sequelize } from 'sequelize' + +export function initStore (sequelize: Sequelize): Promise { + return init(sequelize, { + 'storage.lastProcessedBlock': 'int', + 'rates.lastUpdate': 'int', + 'rns.owner.lastProcessedBlock': 'int', + 'rns.reverse.lastProcessedBlock': 'int', + 'rns.placement.lastProcessedBlock': 'int' + }) +} + +export function configureStore (app: Application): void { + app.set('storeInit', initStore(app.get('sequelize'))) +} diff --git a/src/utils.ts b/src/utils.ts index d3cf69fb..79e48c37 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -4,7 +4,7 @@ import { readFile as readFileCb } from 'fs' import { promisify } from 'util' import config from 'config' -import { Config, Store, Logger } from './definitions' +import { Application, Config, Logger } from './definitions' import { isSupportedServices, SupportedServices } from './app' import { EventData } from 'web3-eth-contract' @@ -16,35 +16,6 @@ export async function asyncFilter (arr: Array, callback: (elem: T) => Prom return mappedArray.filter(i => i !== fail) as T[] } -/** - * Wrap a Store interface into wrapper that scopes all stored values into prefix. - * - * @example - * const originalStore = new Store() - * originalStore.put('some.key', 'value') - * console.log(originalStore.get('some.key') // Print: 'value' - * - * const scopedStore = scopeStore(originalStore, 'some') - * console.log(scopedStore.get('key')) // Print: 'value' - * scopedStore.put('key', 'otherValue') - * - * console.log(originalStore.get('some.key') // Print: 'otherValue' - * - * @param store - * @param prefix - */ -export function scopeStore (store: Store, prefix: string): Store { - return { - get (key: string): any { - return store.get(`${prefix}.${key}`) - }, - - set (key: string, value: any): void { - store.set(`${prefix}.${key}`, value) - } - } -} - export function capitalizeFirstLetter (value: string): string { return value.charAt(0).toUpperCase() + value.slice(1) } @@ -73,6 +44,11 @@ export function errorHandler (fn: (event: EventData) => Promise, logger: L } } +export async function waitForReadyApp (app: Application): Promise { + await app.get('storeInit') + await app.get('sequelizeSync') +} + export abstract class BaseCLICommand extends Command { static flags = { config: flags.string({ diff --git a/test/blockchain/events.spec.ts b/test/blockchain/events.spec.ts index 179cd6aa..4d171e71 100644 --- a/test/blockchain/events.spec.ts +++ b/test/blockchain/events.spec.ts @@ -1,11 +1,11 @@ import { BaseEventsEmitter, - BlockTracker, + BlockTracker, BlockTrackerStore, EventsEmitterOptions, ListeningNewBlockEmitter, PollingEventsEmitter, PollingNewBlockEmitter } from '../../src/blockchain/events' -import { Logger, Store } from '../../src/definitions' +import { Logger } from '../../src/definitions' import { BlockHeader, Eth, TransactionReceipt } from 'web3-eth' import { Arg, Substitute } from '@fluffy-spoon/substitute' @@ -28,22 +28,6 @@ const setImmediatePromise = util.promisify(setImmediate) const NEW_BLOCK_EVENT = 'newBlock' const DATA_EVENT_NAME = 'newEvent' -class StoreMock implements Store { - data: Record = {} - - get (key: string): any { - return this.data[key] - } - - set (key: string, value: any): void { - this.data[key] = value - } - - isEmpty (): boolean { - return Object.keys(this.data).length === 0 - } -} - function sleep (ms: number, ...args: T[]): Promise { return new Promise(resolve => setTimeout(() => resolve(...args), ms)) } @@ -139,23 +123,21 @@ describe('BlockTracker', () => { const STORE_LAST_PROCESSED_BLOCK_KEY = 'lastProcessedBlock' it('read initial block from store', function () { - const store = new StoreMock() - store.set(STORE_LAST_PROCESSED_BLOCK_KEY, 111) - + const store = { [STORE_LAST_PROCESSED_BLOCK_KEY]: 111 } const bt = new BlockTracker(store) expect(bt.getLastProcessedBlock()).to.eql(111) }) it('should save block', function () { - const store = new StoreMock() + const store = {} as BlockTrackerStore const bt = new BlockTracker(store) expect(bt.getLastProcessedBlock()).to.be.undefined() - expect(store.isEmpty()).to.be.true() + expect(store[STORE_LAST_PROCESSED_BLOCK_KEY]).to.be.undefined() bt.setLastProcessedBlock(10) expect(bt.getLastProcessedBlock()).to.eql(10) - expect(store.data[STORE_LAST_PROCESSED_BLOCK_KEY]).to.eql(10) + expect(store[STORE_LAST_PROCESSED_BLOCK_KEY]).to.eql(10) }) }) @@ -286,7 +268,7 @@ describe('BaseEventsEmitter', () => { const contract = Substitute.for() contract.getPastEvents(Arg.all()).returns(sleep(200, events)) - const blockTracker = new BlockTracker(new StoreMock()) + const blockTracker = new BlockTracker({}) const newBlockEmitter = new EventEmitter() const options = { blockTracker, newBlockEmitter } const spy = sinon.spy() @@ -318,7 +300,7 @@ describe('BaseEventsEmitter', () => { const contract = Substitute.for() contract.getPastEvents(Arg.all()).returns(Promise.resolve(events)) - const blockTracker = new BlockTracker(new StoreMock()) + const blockTracker = new BlockTracker({}) const newBlockEmitter = new EventEmitter() const options: EventsEmitterOptions = { confirmations: 2, blockTracker, newBlockEmitter } const spy = sinon.spy() @@ -340,7 +322,7 @@ describe('BaseEventsEmitter', () => { const contract = Substitute.for() contract.getPastEvents(Arg.all()).returns(Promise.resolve([])) - const blockTracker = new BlockTracker(new StoreMock()) + const blockTracker = new BlockTracker({}) const newBlockEmitter = new EventEmitter() const options: EventsEmitterOptions = { confirmations: 2, blockTracker, newBlockEmitter } const spy = sinon.spy() @@ -369,7 +351,7 @@ describe('BaseEventsEmitter', () => { const contract = Substitute.for() contract.getPastEvents(Arg.all()).returns(Promise.resolve([])) - const blockTracker = new BlockTracker(new StoreMock()) + const blockTracker = new BlockTracker({}) const newBlockEmitter = new EventEmitter() const options: EventsEmitterOptions = { confirmations: 2, blockTracker, newBlockEmitter } const spy = sinon.spy() @@ -413,7 +395,7 @@ describe('BaseEventsEmitter', () => { const contract = Substitute.for() contract.getPastEvents(Arg.all()).returns(Promise.resolve([])) - const blockTracker = new BlockTracker(new StoreMock()) + const blockTracker = new BlockTracker({}) const newBlockEmitter = new EventEmitter() const options: EventsEmitterOptions = { confirmations: 2, blockTracker, newBlockEmitter } const emitterSpy = sinon.spy() @@ -422,12 +404,48 @@ describe('BaseEventsEmitter', () => { // Create events to be confirmed const events = [ - { event: 'testEvent', blockNumber: 7, transactionHash: '1', logIndex: 1, content: '{"transactionHash": "1", "blockNumber": 7}' }, - { event: 'testEvent', blockNumber: 8, transactionHash: '2', logIndex: 1, content: '{"transactionHash": "2", "blockNumber": 8}' }, - { event: 'testEvent', blockNumber: 9, transactionHash: '3', logIndex: 1, content: '{"transactionHash": "3", "blockNumber": 9}' }, - { event: 'testEvent', blockNumber: 9, transactionHash: '4', logIndex: 1, content: '{"transactionHash": "4", "blockNumber": 9}' }, - { event: 'testEvent', blockNumber: 10, transactionHash: '5', logIndex: 1, content: '{"transactionHash": "5", "blockNumber": 10}' }, - { event: 'testEvent', blockNumber: 11, transactionHash: '6', logIndex: 1, content: '{"transactionHash": "6", "blockNumber": 11}' } + { + event: 'testEvent', + blockNumber: 7, + transactionHash: '1', + logIndex: 1, + content: '{"transactionHash": "1", "blockNumber": 7}' + }, + { + event: 'testEvent', + blockNumber: 8, + transactionHash: '2', + logIndex: 1, + content: '{"transactionHash": "2", "blockNumber": 8}' + }, + { + event: 'testEvent', + blockNumber: 9, + transactionHash: '3', + logIndex: 1, + content: '{"transactionHash": "3", "blockNumber": 9}' + }, + { + event: 'testEvent', + blockNumber: 9, + transactionHash: '4', + logIndex: 1, + content: '{"transactionHash": "4", "blockNumber": 9}' + }, + { + event: 'testEvent', + blockNumber: 10, + transactionHash: '5', + logIndex: 1, + content: '{"transactionHash": "5", "blockNumber": 10}' + }, + { + event: 'testEvent', + blockNumber: 11, + transactionHash: '6', + logIndex: 1, + content: '{"transactionHash": "6", "blockNumber": 11}' + } ] await Event.bulkCreate(events) @@ -451,7 +469,7 @@ describe('BaseEventsEmitter', () => { const contract = Substitute.for() contract.getPastEvents(Arg.all()).returns(Promise.resolve([])) - const blockTracker = new BlockTracker(new StoreMock()) + const blockTracker = new BlockTracker({}) const newBlockEmitter = new EventEmitter() const options: EventsEmitterOptions = { confirmations: 2, blockTracker, newBlockEmitter } const emitterSpy = sinon.spy() @@ -460,12 +478,48 @@ describe('BaseEventsEmitter', () => { // Create events to be confirmed const events = [ - { event: 'testEvent', blockNumber: 7, transactionHash: '1', logIndex: 1, content: '{"transactionHash": "1", "blockNumber": 7}' }, - { event: 'testEvent', blockNumber: 8, transactionHash: '2', logIndex: 1, content: '{"transactionHash": "2", "blockNumber": 8}' }, - { event: 'testEvent', blockNumber: 9, transactionHash: '3', logIndex: 1, content: '{"transactionHash": "3", "blockNumber": 9}' }, - { event: 'testEvent', blockNumber: 9, transactionHash: '4', logIndex: 1, content: '{"transactionHash": "4", "blockNumber": 9}' }, - { event: 'testEvent', blockNumber: 10, transactionHash: '5', logIndex: 1, content: '{"transactionHash": "5", "blockNumber": 10}' }, - { event: 'testEvent', blockNumber: 11, transactionHash: '6', logIndex: 1, content: '{"transactionHash": "6", "blockNumber": 11}' } + { + event: 'testEvent', + blockNumber: 7, + transactionHash: '1', + logIndex: 1, + content: '{"transactionHash": "1", "blockNumber": 7}' + }, + { + event: 'testEvent', + blockNumber: 8, + transactionHash: '2', + logIndex: 1, + content: '{"transactionHash": "2", "blockNumber": 8}' + }, + { + event: 'testEvent', + blockNumber: 9, + transactionHash: '3', + logIndex: 1, + content: '{"transactionHash": "3", "blockNumber": 9}' + }, + { + event: 'testEvent', + blockNumber: 9, + transactionHash: '4', + logIndex: 1, + content: '{"transactionHash": "4", "blockNumber": 9}' + }, + { + event: 'testEvent', + blockNumber: 10, + transactionHash: '5', + logIndex: 1, + content: '{"transactionHash": "5", "blockNumber": 10}' + }, + { + event: 'testEvent', + blockNumber: 11, + transactionHash: '6', + logIndex: 1, + content: '{"transactionHash": "6", "blockNumber": 11}' + } ] await Event.bulkCreate(events) @@ -490,7 +544,7 @@ describe('BaseEventsEmitter', () => { const contract = Substitute.for() contract.getPastEvents(Arg.all()).returns(Promise.resolve([])) - const firstBlockTracker = new BlockTracker(new StoreMock()) + const firstBlockTracker = new BlockTracker({}) const firstNewBlockEmitter = new EventEmitter() const firstOptions: EventsEmitterOptions = { confirmations: 2, @@ -501,7 +555,7 @@ describe('BaseEventsEmitter', () => { const firstEventsEmitter = new DummyEventsEmitter(eth, contract, ['firstEvent'], firstOptions, 'dummy1') firstEventsEmitter.on(DATA_EVENT_NAME, firstEmitterSpy) - const secondBlockTracker = new BlockTracker(new StoreMock()) + const secondBlockTracker = new BlockTracker({}) const secondNewBlockEmitter = new EventEmitter() const secondOptions: EventsEmitterOptions = { confirmations: 2, @@ -598,7 +652,7 @@ describe('BaseEventsEmitter', () => { const contract = Substitute.for() contract.getPastEvents(Arg.all()).returns(Promise.resolve(events)) - const blockTracker = new BlockTracker(new StoreMock()) + const blockTracker = new BlockTracker({}) const newBlockEmitter = new EventEmitter() const options = { blockTracker, newBlockEmitter } const spy = sinon.spy() @@ -619,7 +673,7 @@ describe('BaseEventsEmitter', () => { const contract = Substitute.for() contract.getPastEvents(Arg.all()).returns(Promise.resolve([])) - const blockTracker = new BlockTracker(new StoreMock()) + const blockTracker = new BlockTracker({}) const newBlockEmitter = new EventEmitter() const options = { blockTracker, newBlockEmitter } const spy = sinon.spy() @@ -653,7 +707,7 @@ describe('PollingEventsEmitter', function () { Promise.resolve([eventMock({ blockNumber: 12, event: 'testEvent', returnValues: { hey: 321 } })]) // Value for polling new events ) - const blockTracker = new BlockTracker(new StoreMock()) + const blockTracker = new BlockTracker({}) blockTracker.setLastProcessedBlock(10) const newBlockEmitter = new EventEmitter() @@ -682,7 +736,7 @@ describe('PollingEventsEmitter', function () { Promise.resolve([]) // Value for polling new events ) - const blockTracker = new BlockTracker(new StoreMock()) + const blockTracker = new BlockTracker({}) blockTracker.setLastProcessedBlock(10) const newBlockEmitter = new EventEmitter() @@ -710,7 +764,7 @@ describe('PollingEventsEmitter', function () { Promise.resolve([eventMock({ blockNumber: 11 })]) // Value for polling new events ) - const blockTracker = new BlockTracker(new StoreMock()) + const blockTracker = new BlockTracker({}) blockTracker.setLastProcessedBlock(10) const newBlockEmitter = new EventEmitter() @@ -745,7 +799,7 @@ describe('PollingEventsEmitter', function () { const contract = Substitute.for() contract.getPastEvents(Arg.all()).returns(sleep(200, events), Promise.resolve(events)) - const blockTracker = new BlockTracker(new StoreMock()) + const blockTracker = new BlockTracker({}) const newBlockEmitter = new EventEmitter() const options = { blockTracker, newBlockEmitter } const spy = sinon.spy()