@audius/sdk 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (278) hide show
  1. package/.eslintrc +38 -0
  2. package/.prettierrc.js +1 -0
  3. package/.python-version +1 -0
  4. package/Dockerfile +15 -0
  5. package/README.md +3 -0
  6. package/babel.config.js +3 -0
  7. package/data-contracts/ABIs/AdminUpgradeabilityProxy.json +132 -0
  8. package/data-contracts/ABIs/BaseAdminUpgradeabilityProxy.json +113 -0
  9. package/data-contracts/ABIs/BaseUpgradeabilityProxy.json +22 -0
  10. package/data-contracts/ABIs/DiscoveryProviderFactory.json +189 -0
  11. package/data-contracts/ABIs/DiscoveryProviderFactoryInterface.json +61 -0
  12. package/data-contracts/ABIs/DiscoveryProviderStorage.json +205 -0
  13. package/data-contracts/ABIs/DiscoveryProviderStorageInterface.json +65 -0
  14. package/data-contracts/ABIs/ECDSA.json +4 -0
  15. package/data-contracts/ABIs/IPLDBlacklistFactory.json +168 -0
  16. package/data-contracts/ABIs/Initializable.json +4 -0
  17. package/data-contracts/ABIs/Migrations.json +67 -0
  18. package/data-contracts/ABIs/OpenZeppelinUpgradesAddress.json +4 -0
  19. package/data-contracts/ABIs/Ownable.json +79 -0
  20. package/data-contracts/ABIs/PlaylistFactory.json +669 -0
  21. package/data-contracts/ABIs/PlaylistFactoryInterface.json +42 -0
  22. package/data-contracts/ABIs/PlaylistStorage.json +250 -0
  23. package/data-contracts/ABIs/PlaylistStorageInterface.json +129 -0
  24. package/data-contracts/ABIs/Proxy.json +10 -0
  25. package/data-contracts/ABIs/Registry.json +240 -0
  26. package/data-contracts/ABIs/RegistryContract.json +102 -0
  27. package/data-contracts/ABIs/RegistryContractInterface.json +28 -0
  28. package/data-contracts/ABIs/RegistryInterface.json +66 -0
  29. package/data-contracts/ABIs/SigningLogic.json +43 -0
  30. package/data-contracts/ABIs/SigningLogicInitializable.json +46 -0
  31. package/data-contracts/ABIs/SocialFeatureFactory.json +460 -0
  32. package/data-contracts/ABIs/SocialFeatureStorage.json +225 -0
  33. package/data-contracts/ABIs/SocialFeatureStorageInterface.json +123 -0
  34. package/data-contracts/ABIs/TestContract.json +135 -0
  35. package/data-contracts/ABIs/TestContractInterface.json +19 -0
  36. package/data-contracts/ABIs/TestContractWithStorage.json +165 -0
  37. package/data-contracts/ABIs/TestContractWithStorageInterface.json +24 -0
  38. package/data-contracts/ABIs/TestStorage.json +144 -0
  39. package/data-contracts/ABIs/TestStorageInterface.json +42 -0
  40. package/data-contracts/ABIs/TestUserReplicaSetManager.json +432 -0
  41. package/data-contracts/ABIs/TrackFactory.json +391 -0
  42. package/data-contracts/ABIs/TrackFactoryInterface.json +73 -0
  43. package/data-contracts/ABIs/TrackStorage.json +223 -0
  44. package/data-contracts/ABIs/TrackStorageInterface.json +121 -0
  45. package/data-contracts/ABIs/UpgradeabilityProxy.json +37 -0
  46. package/data-contracts/ABIs/UserFactory.json +657 -0
  47. package/data-contracts/ABIs/UserFactoryInterface.json +65 -0
  48. package/data-contracts/ABIs/UserLibraryFactory.json +334 -0
  49. package/data-contracts/ABIs/UserReplicaSetManager.json +418 -0
  50. package/data-contracts/ABIs/UserStorage.json +233 -0
  51. package/data-contracts/ABIs/UserStorageInterface.json +93 -0
  52. package/data-contracts/signatureSchemas.ts +1236 -0
  53. package/dist/core.d.ts +446 -0
  54. package/dist/core.js +769 -0
  55. package/dist/core.js.map +1 -0
  56. package/dist/index.d.ts +689 -0
  57. package/dist/index.js +72850 -0
  58. package/dist/index.js.map +1 -0
  59. package/eth-contracts/ABIs/Address.json +4 -0
  60. package/eth-contracts/ABIs/AudiusAdminUpgradeabilityProxy.json +105 -0
  61. package/eth-contracts/ABIs/AudiusClaimDistributor.json +4968 -0
  62. package/eth-contracts/ABIs/AudiusToken.json +724 -0
  63. package/eth-contracts/ABIs/BaseUpgradeabilityProxy.json +23 -0
  64. package/eth-contracts/ABIs/Checkpointing.json +4 -0
  65. package/eth-contracts/ABIs/ClaimsManager.json +539 -0
  66. package/eth-contracts/ABIs/Context.json +11 -0
  67. package/eth-contracts/ABIs/DelegateManager.json +989 -0
  68. package/eth-contracts/ABIs/DelegateManagerV2.json +1049 -0
  69. package/eth-contracts/ABIs/DelegateManagerV2Bad.json +1049 -0
  70. package/eth-contracts/ABIs/ERC20.json +252 -0
  71. package/eth-contracts/ABIs/ERC20Burnable.json +287 -0
  72. package/eth-contracts/ABIs/ERC20Detailed.json +270 -0
  73. package/eth-contracts/ABIs/ERC20Mintable.json +364 -0
  74. package/eth-contracts/ABIs/ERC20Pausable.json +397 -0
  75. package/eth-contracts/ABIs/EthRewardsManager.json +174 -0
  76. package/eth-contracts/ABIs/Governance.json +938 -0
  77. package/eth-contracts/ABIs/GovernanceUpgraded.json +953 -0
  78. package/eth-contracts/ABIs/GovernanceV2.json +938 -0
  79. package/eth-contracts/ABIs/IERC20.json +200 -0
  80. package/eth-contracts/ABIs/Initializable.json +4 -0
  81. package/eth-contracts/ABIs/InitializableV2.json +14 -0
  82. package/eth-contracts/ABIs/Migrations.json +71 -0
  83. package/eth-contracts/ABIs/MinterRole.json +91 -0
  84. package/eth-contracts/ABIs/MockAccount.json +62 -0
  85. package/eth-contracts/ABIs/MockDelegateManager.json +55 -0
  86. package/eth-contracts/ABIs/MockStakingCaller.json +259 -0
  87. package/eth-contracts/ABIs/MockWormhole.json +106 -0
  88. package/eth-contracts/ABIs/OpenZeppelinUpgradesAddress.json +4 -0
  89. package/eth-contracts/ABIs/Ownable.json +93 -0
  90. package/eth-contracts/ABIs/Pausable.json +150 -0
  91. package/eth-contracts/ABIs/PauserRole.json +91 -0
  92. package/eth-contracts/ABIs/Proxy.json +10 -0
  93. package/eth-contracts/ABIs/Registry.json +288 -0
  94. package/eth-contracts/ABIs/Roles.json +4 -0
  95. package/eth-contracts/ABIs/SafeERC20.json +4 -0
  96. package/eth-contracts/ABIs/SafeMath.json +4 -0
  97. package/eth-contracts/ABIs/ServiceProviderFactory.json +1153 -0
  98. package/eth-contracts/ABIs/ServiceTypeManager.json +337 -0
  99. package/eth-contracts/ABIs/Staking.json +555 -0
  100. package/eth-contracts/ABIs/StakingUpgraded.json +570 -0
  101. package/eth-contracts/ABIs/TestContract.json +44 -0
  102. package/eth-contracts/ABIs/TrustedNotifierManager.json +265 -0
  103. package/eth-contracts/ABIs/Uint256Helpers.json +4 -0
  104. package/eth-contracts/ABIs/UpgradeabilityProxy.json +40 -0
  105. package/eth-contracts/ABIs/Wormhole.json +45 -0
  106. package/eth-contracts/ABIs/WormholeClient.json +155 -0
  107. package/examples/file.mp3 +0 -0
  108. package/examples/initAudiusLibs.js +86 -0
  109. package/examples/initializeVersions.js +95 -0
  110. package/examples/pic.jpg +0 -0
  111. package/initScripts/configureLocalDiscProv.js +167 -0
  112. package/initScripts/helpers/claim.js +43 -0
  113. package/initScripts/helpers/distributeTokens.js +24 -0
  114. package/initScripts/helpers/spRegistration.js +138 -0
  115. package/initScripts/helpers/utils.js +34 -0
  116. package/initScripts/helpers/version.js +93 -0
  117. package/initScripts/local.js +617 -0
  118. package/initScripts/mainnet.js +131 -0
  119. package/initScripts/manageProdRelayerWallets.js +191 -0
  120. package/package.json +125 -0
  121. package/rollup.config.js +164 -0
  122. package/scripts/AudiusClaimDistributor.json +4968 -0
  123. package/scripts/Wormhole.json +155 -0
  124. package/scripts/addCIDToIpldBlacklist.js +124 -0
  125. package/scripts/circleci-test.sh +53 -0
  126. package/scripts/communityRewards/transferCommunityRewardsToSolana.js +222 -0
  127. package/scripts/ipfs.sh +58 -0
  128. package/scripts/migrate_contracts.sh +25 -0
  129. package/scripts/reset.sh +65 -0
  130. package/scripts/test.sh +77 -0
  131. package/src/api/account.js +670 -0
  132. package/src/api/base.js +122 -0
  133. package/src/api/file.js +168 -0
  134. package/src/api/playlist.js +328 -0
  135. package/src/api/rewards.d.ts +4 -0
  136. package/src/api/rewards.js +682 -0
  137. package/src/api/serviceProvider.js +154 -0
  138. package/src/api/track.js +604 -0
  139. package/src/api/user.js +888 -0
  140. package/src/api/user.test.js +172 -0
  141. package/src/constants.ts +7 -0
  142. package/src/core.ts +3 -0
  143. package/src/index.js +6 -0
  144. package/src/libs.d.ts +3 -0
  145. package/src/libs.js +619 -0
  146. package/src/sanityChecks/addSecondaries.js +40 -0
  147. package/src/sanityChecks/assignReplicaSetIfNecessary.js +10 -0
  148. package/src/sanityChecks/index.d.ts +9 -0
  149. package/src/sanityChecks/index.js +31 -0
  150. package/src/sanityChecks/isCreator.js +73 -0
  151. package/src/sanityChecks/needsRecoveryEmail.js +20 -0
  152. package/src/sanityChecks/rolloverNodes.js +74 -0
  153. package/src/sanityChecks/sanitizeNodes.js +24 -0
  154. package/src/sanityChecks/syncNodes.js +28 -0
  155. package/src/sdk/constants.ts +10 -0
  156. package/src/sdk/index.ts +1 -0
  157. package/src/sdk/oauth/Oauth.ts +265 -0
  158. package/src/sdk/oauth/index.ts +1 -0
  159. package/src/sdk/sdk.ts +102 -0
  160. package/src/service-selection/ServiceSelection.test.ts +320 -0
  161. package/src/service-selection/ServiceSelection.ts +460 -0
  162. package/src/service-selection/constants.ts +14 -0
  163. package/src/service-selection/index.ts +1 -0
  164. package/src/services/ABIDecoder/AudiusABIDecoder.ts +71 -0
  165. package/src/services/ABIDecoder/index.ts +1 -0
  166. package/src/services/comstock/Comstock.ts +39 -0
  167. package/src/services/comstock/index.ts +1 -0
  168. package/src/services/contracts/ContractClient.ts +227 -0
  169. package/src/services/contracts/GovernedContractClient.ts +53 -0
  170. package/src/services/contracts/ProviderSelection.ts +42 -0
  171. package/src/services/creatorNode/CreatorNode.ts +1065 -0
  172. package/src/services/creatorNode/CreatorNodeSelection.test.ts +997 -0
  173. package/src/services/creatorNode/CreatorNodeSelection.ts +488 -0
  174. package/src/services/creatorNode/constants.ts +10 -0
  175. package/src/services/creatorNode/index.ts +2 -0
  176. package/src/services/dataContracts/AudiusContracts.ts +234 -0
  177. package/src/services/dataContracts/IPLDBlacklistFactoryClient.ts +73 -0
  178. package/src/services/dataContracts/PlaylistFactoryClient.ts +370 -0
  179. package/src/services/dataContracts/RegistryClient.ts +95 -0
  180. package/src/services/dataContracts/SocialFeatureFactoryClient.ts +196 -0
  181. package/src/services/dataContracts/TrackFactoryClient.ts +131 -0
  182. package/src/services/dataContracts/UserFactoryClient.ts +351 -0
  183. package/src/services/dataContracts/UserLibraryFactoryClient.ts +115 -0
  184. package/src/services/dataContracts/UserReplicaSetManagerClient.ts +206 -0
  185. package/src/services/dataContracts/index.ts +1 -0
  186. package/src/services/discoveryProvider/DiscoveryProvider.ts +1168 -0
  187. package/src/services/discoveryProvider/DiscoveryProviderSelection.test.ts +536 -0
  188. package/src/services/discoveryProvider/DiscoveryProviderSelection.ts +383 -0
  189. package/src/services/discoveryProvider/constants.ts +13 -0
  190. package/src/services/discoveryProvider/index.ts +1 -0
  191. package/src/services/discoveryProvider/requests.ts +629 -0
  192. package/src/services/ethContracts/AudiusTokenClient.ts +163 -0
  193. package/src/services/ethContracts/ClaimDistributionClient.ts +45 -0
  194. package/src/services/ethContracts/ClaimsManagerClient.ts +102 -0
  195. package/src/services/ethContracts/DelegateManagerClient.ts +480 -0
  196. package/src/services/ethContracts/EthContracts.ts +359 -0
  197. package/src/services/ethContracts/EthRewardsManagerClient.ts +33 -0
  198. package/src/services/ethContracts/GovernanceClient.ts +451 -0
  199. package/src/services/ethContracts/RegistryClient.ts +33 -0
  200. package/src/services/ethContracts/ServiceProviderFactoryClient.ts +691 -0
  201. package/src/services/ethContracts/ServiceTypeManagerClient.ts +112 -0
  202. package/src/services/ethContracts/StakingProxyClient.ts +97 -0
  203. package/src/services/ethContracts/TrustedNotifierManagerClient.ts +101 -0
  204. package/src/services/ethContracts/WormholeClient.ts +97 -0
  205. package/src/services/ethContracts/index.ts +1 -0
  206. package/src/services/ethWeb3Manager/EthWeb3Manager.ts +239 -0
  207. package/src/services/ethWeb3Manager/index.ts +1 -0
  208. package/src/services/hedgehog/Hedgehog.ts +96 -0
  209. package/src/services/hedgehog/index.ts +1 -0
  210. package/src/services/identity/IdentityService.ts +551 -0
  211. package/src/services/identity/index.ts +1 -0
  212. package/src/services/identity/requests.ts +65 -0
  213. package/src/services/schemaValidator/SchemaValidator.ts +105 -0
  214. package/src/services/schemaValidator/index.ts +1 -0
  215. package/src/services/schemaValidator/schemas/trackSchema.json +267 -0
  216. package/src/services/schemaValidator/schemas/userSchema.json +230 -0
  217. package/src/services/solanaAudiusData/errors.ts +20 -0
  218. package/src/services/solanaAudiusData/index.ts +1189 -0
  219. package/src/services/solanaWeb3Manager/errors.js +101 -0
  220. package/src/services/solanaWeb3Manager/index.d.ts +46 -0
  221. package/src/services/solanaWeb3Manager/index.js +655 -0
  222. package/src/services/solanaWeb3Manager/padBNToUint8Array.ts +7 -0
  223. package/src/services/solanaWeb3Manager/rewards.js +941 -0
  224. package/src/services/solanaWeb3Manager/rewardsAttester.ts +1093 -0
  225. package/src/services/solanaWeb3Manager/tokenAccount.js +149 -0
  226. package/src/services/solanaWeb3Manager/transactionHandler.js +345 -0
  227. package/src/services/solanaWeb3Manager/transfer.js +272 -0
  228. package/src/services/solanaWeb3Manager/userBank.js +160 -0
  229. package/src/services/solanaWeb3Manager/utils.d.ts +31 -0
  230. package/src/services/solanaWeb3Manager/utils.js +163 -0
  231. package/src/services/solanaWeb3Manager/wAudio.js +28 -0
  232. package/src/services/solanaWeb3Manager/wAudio.test.js +30 -0
  233. package/src/services/web3Manager/Web3Config.ts +14 -0
  234. package/src/services/web3Manager/Web3Manager.ts +360 -0
  235. package/src/services/web3Manager/XMLHttpRequest.ts +11 -0
  236. package/src/services/web3Manager/index.ts +2 -0
  237. package/src/services/wormhole/index.js +424 -0
  238. package/src/types.ts +8 -0
  239. package/src/userStateManager.ts +53 -0
  240. package/src/utils/apiSigning.ts +51 -0
  241. package/src/utils/captcha.ts +97 -0
  242. package/src/utils/estimateGas.ts +64 -0
  243. package/src/utils/fileHasher.ts +278 -0
  244. package/src/utils/importContractABI.d.ts +9 -0
  245. package/src/utils/importContractABI.js +19 -0
  246. package/src/utils/index.ts +11 -0
  247. package/src/utils/multiProvider.ts +72 -0
  248. package/src/utils/network.test.ts +127 -0
  249. package/src/utils/network.ts +308 -0
  250. package/src/utils/promiseFight.test.ts +87 -0
  251. package/src/utils/promiseFight.ts +36 -0
  252. package/src/utils/signatures.ts +139 -0
  253. package/src/utils/types.ts +34 -0
  254. package/src/utils/utils.test.ts +36 -0
  255. package/src/utils/utils.ts +235 -0
  256. package/src/utils/uuid.ts +14 -0
  257. package/src/web3.d.ts +9 -0
  258. package/src/web3.js +8 -0
  259. package/tests/assets/static_image.png +0 -0
  260. package/tests/assets/static_text.txt +1 -0
  261. package/tests/audiusTokenClientTest.js +37 -0
  262. package/tests/creatorNodeTest.js +19 -0
  263. package/tests/fileHasherTest.js +125 -0
  264. package/tests/governanceTest.js +382 -0
  265. package/tests/helpers.js +105 -0
  266. package/tests/index.js +14 -0
  267. package/tests/playlistClientTest.js +157 -0
  268. package/tests/providerSelectionTest.js +241 -0
  269. package/tests/registryClientTest.js +19 -0
  270. package/tests/rewardsAttesterTest.js +373 -0
  271. package/tests/serviceTypeManagerClientTest.js +33 -0
  272. package/tests/socialFeatureClientTest.js +79 -0
  273. package/tests/stakingTest.js +302 -0
  274. package/tests/trackClientTest.js +86 -0
  275. package/tests/userClientTest.js +121 -0
  276. package/tsconfig.json +10 -0
  277. package/types/@audius-hedgehog/index.d.ts +39 -0
  278. package/types/abi-decoder/index.d.ts +41 -0
@@ -0,0 +1,536 @@
1
+ import nock from 'nock'
2
+ import assert from 'assert'
3
+ import semver from 'semver'
4
+ import { DiscoveryProviderSelection } from './DiscoveryProviderSelection'
5
+ import { DISCOVERY_PROVIDER_TIMESTAMP } from './constants'
6
+ import type { EthContracts } from '../ethContracts'
7
+ import { LocalStorage } from 'node-localstorage'
8
+
9
+ const mockEthContracts = (
10
+ urls: string[],
11
+ currrentVersion: string,
12
+ previousVersions: string[] | null = null
13
+ ): EthContracts =>
14
+ ({
15
+ getCurrentVersion: async () => currrentVersion,
16
+ getNumberOfVersions: async (_: string) => 2,
17
+ getVersion: async (_: string, queryIndex: number): Promise<string> => {
18
+ if (previousVersions) {
19
+ return previousVersions[queryIndex] as string
20
+ }
21
+ return ['1.2.2', '1.2.3'][queryIndex] as string
22
+ },
23
+ getServiceProviderList: async () => urls.map((u) => ({ endpoint: u })),
24
+ hasSameMajorAndMinorVersion: (version1: string, version2: string) => {
25
+ return (
26
+ semver.major(version1) === semver.major(version2) &&
27
+ semver.minor(version1) === semver.minor(version2)
28
+ )
29
+ },
30
+ isInRegressedMode: () => {
31
+ return false
32
+ }
33
+ } as unknown as EthContracts)
34
+
35
+ describe('DiscoveryProviderSelection', () => {
36
+ beforeEach(() => {
37
+ const localStorage = new LocalStorage('./local-storage')
38
+ localStorage.removeItem(DISCOVERY_PROVIDER_TIMESTAMP)
39
+ })
40
+ afterEach(() => {
41
+ nock.cleanAll()
42
+ })
43
+
44
+ it('selects a healthy service', async () => {
45
+ const healthy = 'https://healthy.audius.co'
46
+ nock(healthy)
47
+ .get('/health_check')
48
+ .reply(200, {
49
+ data: {
50
+ service: 'discovery-node',
51
+ version: '1.2.3',
52
+ block_difference: 0
53
+ }
54
+ })
55
+
56
+ const s = new DiscoveryProviderSelection(
57
+ {},
58
+ mockEthContracts([healthy], '1.2.3')
59
+ )
60
+ const service = await s.select()
61
+ assert.strictEqual(service, healthy)
62
+ })
63
+
64
+ it('selects a healthy service with an unhealthy one present', async () => {
65
+ const healthy = 'https://healthy.audius.co'
66
+ nock(healthy)
67
+ .get('/health_check')
68
+ .reply(200, {
69
+ data: {
70
+ service: 'discovery-node',
71
+ version: '1.2.3',
72
+ block_difference: 0
73
+ }
74
+ })
75
+ const unhealthy = 'https://unhealthy.audius.co'
76
+ nock(unhealthy)
77
+ .get('/health_check')
78
+ .reply(400, {
79
+ data: {
80
+ service: 'discovery-node',
81
+ version: '1.2.3',
82
+ block_difference: 0
83
+ }
84
+ })
85
+
86
+ const s = new DiscoveryProviderSelection(
87
+ {},
88
+ mockEthContracts([healthy, unhealthy], '1.2.3')
89
+ )
90
+ const service = await s.select()
91
+ assert.strictEqual(service, healthy)
92
+ })
93
+
94
+ it('prefers the correct vesion', async () => {
95
+ const healthy = 'https://healthy.audius.co'
96
+ nock(healthy)
97
+ .get('/health_check')
98
+ .reply(200, {
99
+ data: {
100
+ service: 'discovery-node',
101
+ version: '1.2.3',
102
+ block_difference: 0
103
+ }
104
+ })
105
+ const outdated = 'https://outdated.audius.co'
106
+ nock(outdated)
107
+ .get('/health_check')
108
+ .reply(200, {
109
+ data: {
110
+ service: 'discovery-node',
111
+ version: '1.2.2',
112
+ block_difference: 0
113
+ }
114
+ })
115
+
116
+ const s = new DiscoveryProviderSelection(
117
+ {},
118
+ mockEthContracts([healthy, outdated], '1.2.3')
119
+ )
120
+ const service = await s.select()
121
+ assert.strictEqual(service, healthy)
122
+ })
123
+
124
+ it('prefers a healthy block diff', async () => {
125
+ const healthy = 'https://healthy.audius.co'
126
+ nock(healthy)
127
+ .get('/health_check')
128
+ .reply(200, {
129
+ data: {
130
+ service: 'discovery-node',
131
+ version: '1.2.3',
132
+ block_difference: 0
133
+ }
134
+ })
135
+ const behind = 'https://behind.audius.co'
136
+ nock(behind)
137
+ .get('/health_check')
138
+ .reply(200, {
139
+ data: {
140
+ service: 'discovery-node',
141
+ version: '1.2.3',
142
+ block_difference: 20
143
+ }
144
+ })
145
+
146
+ const s = new DiscoveryProviderSelection(
147
+ {},
148
+ mockEthContracts([healthy, behind], '1.2.3')
149
+ )
150
+ const service = await s.select()
151
+ assert.strictEqual(service, healthy)
152
+ })
153
+
154
+ it('prefers a healthy block diff with custom block diff', async () => {
155
+ const healthyBehindVersion = 'https://healthy.audius.co'
156
+ nock(healthyBehindVersion)
157
+ .get('/health_check')
158
+ .reply(200, {
159
+ data: {
160
+ service: 'discovery-node',
161
+ version: '1.2.2',
162
+ block_difference: 0
163
+ }
164
+ })
165
+ const behindBlockCurrentVersion = 'https://behind.audius.co'
166
+ nock(behindBlockCurrentVersion)
167
+ .get('/health_check')
168
+ .reply(200, {
169
+ data: {
170
+ service: 'discovery-node',
171
+ version: '1.2.3',
172
+ block_difference: 20
173
+ }
174
+ })
175
+
176
+ const s = new DiscoveryProviderSelection(
177
+ {
178
+ unhealthyBlockDiff: 25
179
+ },
180
+ mockEthContracts(
181
+ [healthyBehindVersion, behindBlockCurrentVersion],
182
+ '1.2.3'
183
+ )
184
+ )
185
+ const service = await s.select()
186
+ assert.strictEqual(service, behindBlockCurrentVersion)
187
+ })
188
+
189
+ it('prefers a healthy plays slot diff', async () => {
190
+ const healthy = 'https://healthy.audius.co'
191
+ nock(healthy)
192
+ .get('/health_check')
193
+ .reply(200, {
194
+ data: {
195
+ service: 'discovery-node',
196
+ version: '1.2.3',
197
+ block_difference: 0,
198
+ plays: {
199
+ tx_info: {
200
+ slot_diff: 0
201
+ }
202
+ }
203
+ }
204
+ })
205
+ const behind = 'https://behind.audius.co'
206
+ nock(behind)
207
+ .get('/health_check')
208
+ .reply(200, {
209
+ data: {
210
+ service: 'discovery-node',
211
+ version: '1.2.3',
212
+ block_difference: 0,
213
+ plays: {
214
+ tx_info: {
215
+ slot_diff: 20
216
+ }
217
+ }
218
+ }
219
+ })
220
+
221
+ const s = new DiscoveryProviderSelection(
222
+ {
223
+ unhealthySlotDiffPlays: 10
224
+ },
225
+ mockEthContracts([healthy, behind], '1.2.3')
226
+ )
227
+ const service = await s.select()
228
+ assert.strictEqual(service, healthy)
229
+ })
230
+
231
+ it('can select an old version', async () => {
232
+ const healthyButBehind = 'https://healthyButBehind.audius.co'
233
+ nock(healthyButBehind)
234
+ .get('/health_check')
235
+ .reply(200, {
236
+ data: {
237
+ service: 'discovery-node',
238
+ version: '1.2.3',
239
+ block_difference: 20
240
+ }
241
+ })
242
+ const pastVersionNotBehind = 'https://pastVersionNotBehind.audius.co'
243
+ nock(pastVersionNotBehind)
244
+ .get('/health_check')
245
+ .reply(200, {
246
+ data: {
247
+ service: 'discovery-node',
248
+ version: '1.2.2',
249
+ block_difference: 0
250
+ }
251
+ })
252
+
253
+ const s = new DiscoveryProviderSelection(
254
+ { requestTimeout: 100 },
255
+ mockEthContracts([healthyButBehind, pastVersionNotBehind], '1.2.3')
256
+ )
257
+ const service = await s.select()
258
+ assert.strictEqual(service, pastVersionNotBehind)
259
+ assert.deepStrictEqual(s.backups, {
260
+ [healthyButBehind]: {
261
+ service: 'discovery-node',
262
+ version: '1.2.3',
263
+ block_difference: 20
264
+ },
265
+ [pastVersionNotBehind]: {
266
+ service: 'discovery-node',
267
+ version: '1.2.2',
268
+ block_difference: 0
269
+ }
270
+ })
271
+ assert.strictEqual(s.getTotalAttempts(), 2)
272
+ })
273
+
274
+ it('can select the discprov that is the least number of blocks behind for the current version', async () => {
275
+ const behind20 = 'https://behind20.audius.co'
276
+ nock(behind20)
277
+ .get('/health_check')
278
+ .reply(200, {
279
+ data: {
280
+ service: 'discovery-node',
281
+ version: '1.2.2',
282
+ block_difference: 20
283
+ }
284
+ })
285
+ const behind40 = 'https://behind40.audius.co'
286
+ nock(behind40)
287
+ .get('/health_check')
288
+ .reply(200, {
289
+ data: {
290
+ service: 'discovery-node',
291
+ version: '1.2.3',
292
+ block_difference: 40
293
+ }
294
+ })
295
+
296
+ const s = new DiscoveryProviderSelection(
297
+ { requestTimeout: 100 },
298
+ mockEthContracts([behind20, behind40], '1.2.3')
299
+ )
300
+ const service = await s.select()
301
+ assert.strictEqual(service, behind20)
302
+ assert.deepStrictEqual(s.backups, {
303
+ [behind20]: {
304
+ service: 'discovery-node',
305
+ version: '1.2.2',
306
+ block_difference: 20
307
+ },
308
+ [behind40]: {
309
+ service: 'discovery-node',
310
+ version: '1.2.3',
311
+ block_difference: 40
312
+ }
313
+ })
314
+ assert.strictEqual(s.getTotalAttempts(), 2)
315
+ assert.strictEqual(s.isInRegressedMode(), true)
316
+ })
317
+
318
+ it('can select the discprov that is the least number of blocks behind for past versions', async () => {
319
+ const behind100 = 'https://behind100.audius.co'
320
+ nock(behind100)
321
+ .get('/health_check')
322
+ .reply(200, {
323
+ data: {
324
+ service: 'discovery-node',
325
+ version: '1.2.3',
326
+ block_difference: 100
327
+ }
328
+ })
329
+ const behind200 = 'https://behind200.audius.co'
330
+ nock(behind200)
331
+ .get('/health_check')
332
+ .reply(200, {
333
+ data: {
334
+ service: 'discovery-node',
335
+ version: '1.2.3',
336
+ block_difference: 200
337
+ }
338
+ })
339
+
340
+ const s = new DiscoveryProviderSelection(
341
+ { requestTimeout: 100 },
342
+ mockEthContracts([behind100, behind200], '1.2.0', ['1.2.0'])
343
+ )
344
+ const service = await s.select()
345
+ assert.strictEqual(service, behind100)
346
+ assert.deepStrictEqual(s.backups, {
347
+ [behind100]: {
348
+ service: 'discovery-node',
349
+ version: '1.2.3',
350
+ block_difference: 100
351
+ },
352
+ [behind200]: {
353
+ service: 'discovery-node',
354
+ version: '1.2.3',
355
+ block_difference: 200
356
+ }
357
+ })
358
+ assert.strictEqual(s.getTotalAttempts(), 2)
359
+ assert.strictEqual(s.isInRegressedMode(), true)
360
+ })
361
+
362
+ it('will not pick a minor version behind provider', async () => {
363
+ const minorBehind = 'https://minorBehind.audius.co'
364
+ nock(minorBehind)
365
+ .get('/health_check')
366
+ .reply(200, {
367
+ data: {
368
+ service: 'discovery-node',
369
+ version: '1.1.3',
370
+ block_difference: 20
371
+ }
372
+ })
373
+ const s = new DiscoveryProviderSelection(
374
+ { requestTimeout: 100 },
375
+ mockEthContracts([minorBehind], '1.2.3')
376
+ )
377
+ const service = await s.select()
378
+ assert.strictEqual(service, null)
379
+ })
380
+
381
+ it('respects a whitelist', async () => {
382
+ const healthy1 = 'https://healthy1.audius.co'
383
+ nock(healthy1)
384
+ .get('/health_check')
385
+ .reply(200, {
386
+ data: {
387
+ service: 'discovery-node',
388
+ version: '1.2.3',
389
+ block_difference: 0
390
+ }
391
+ })
392
+
393
+ const healthy2 = 'https://healthy2.audius.co'
394
+ nock(healthy2)
395
+ .get('/health_check')
396
+ .reply(200, {
397
+ data: {
398
+ service: 'discovery-node',
399
+ version: '1.2.3',
400
+ block_difference: 0
401
+ }
402
+ })
403
+
404
+ const s = new DiscoveryProviderSelection(
405
+ {
406
+ whitelist: new Set([healthy2])
407
+ },
408
+ mockEthContracts([healthy1, healthy2], '1.2.3')
409
+ )
410
+ const service = await s.select()
411
+ assert.strictEqual(service, healthy2)
412
+ })
413
+
414
+ it('will cache its choice', async () => {
415
+ const localStorage = new LocalStorage('./local-storage')
416
+
417
+ const healthy1 = 'https://healthy1.audius.co'
418
+ nock(healthy1)
419
+ .get('/health_check')
420
+ .reply(200, {
421
+ data: {
422
+ service: 'discovery-node',
423
+ version: '1.2.3',
424
+ block_difference: 0
425
+ }
426
+ })
427
+
428
+ const s = new DiscoveryProviderSelection(
429
+ {},
430
+ mockEthContracts([healthy1], '1.2.3')
431
+ )
432
+ const service = await s.select()
433
+ assert.strictEqual(service, healthy1)
434
+ const { endpoint } = JSON.parse(
435
+ localStorage.getItem(DISCOVERY_PROVIDER_TIMESTAMP) ?? '{}'
436
+ )
437
+ assert.strictEqual(endpoint, healthy1)
438
+ })
439
+
440
+ it('will cache its choice and reuse it', async () => {
441
+ const localStorage = new LocalStorage('./local-storage')
442
+
443
+ const healthy1 = 'https://healthy1.audius.co'
444
+ nock(healthy1)
445
+ .get('/health_check')
446
+ .delay(100)
447
+ .reply(200, {
448
+ data: {
449
+ service: 'discovery-node',
450
+ version: '1.2.3',
451
+ block_difference: 0
452
+ }
453
+ })
454
+
455
+ const healthy2 = 'https://healthy2.audius.co'
456
+ nock(healthy2)
457
+ .get('/health_check')
458
+ .delay(100)
459
+ .reply(200, {
460
+ data: {
461
+ service: 'discovery-node',
462
+ version: '1.2.3',
463
+ block_difference: 0
464
+ }
465
+ })
466
+
467
+ const initiallyUnhealthy = 'https://initiallyUnhealthy.audius.co'
468
+ nock(initiallyUnhealthy)
469
+ .get('/health_check')
470
+ .reply(400, {
471
+ data: {
472
+ service: 'discovery-node',
473
+ version: '1.2.3',
474
+ block_difference: 0
475
+ }
476
+ })
477
+
478
+ const s = new DiscoveryProviderSelection(
479
+ {},
480
+ mockEthContracts([healthy1, healthy2, initiallyUnhealthy], '1.2.3')
481
+ )
482
+ const firstService = await s.select()
483
+ const { endpoint } = JSON.parse(
484
+ localStorage.getItem(DISCOVERY_PROVIDER_TIMESTAMP) ?? '{}'
485
+ )
486
+ assert.strictEqual(endpoint, firstService)
487
+
488
+ const secondService = await s.select()
489
+ assert.strictEqual(firstService, secondService)
490
+
491
+ const thirdService = await s.select()
492
+ assert.strictEqual(firstService, thirdService)
493
+
494
+ const fourthService = await s.select()
495
+ assert.strictEqual(firstService, fourthService)
496
+
497
+ // Clear the cached service
498
+ s.clearUnhealthy()
499
+ localStorage.removeItem(DISCOVERY_PROVIDER_TIMESTAMP)
500
+
501
+ // Make healthy1 start failing but healthy2 succeed
502
+ nock(healthy1)
503
+ .get('/health_check')
504
+ .reply(400, {
505
+ data: {
506
+ service: 'discovery-node',
507
+ version: '1.2.3',
508
+ block_difference: 0
509
+ }
510
+ })
511
+ nock(healthy2)
512
+ .get('/health_check')
513
+ .reply(400, {
514
+ data: {
515
+ service: 'discovery-node',
516
+ version: '1.2.3',
517
+ block_difference: 0
518
+ }
519
+ })
520
+ nock(initiallyUnhealthy)
521
+ .get('/health_check')
522
+ .reply(200, {
523
+ data: {
524
+ service: 'discovery-node',
525
+ version: '1.2.3',
526
+ block_difference: 0
527
+ }
528
+ })
529
+
530
+ const fifthService = await s.select()
531
+ assert.strictEqual(fifthService, initiallyUnhealthy)
532
+
533
+ const sixthService = await s.select()
534
+ assert.strictEqual(sixthService, initiallyUnhealthy)
535
+ })
536
+ })