@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.
- package/.eslintrc +38 -0
- package/.prettierrc.js +1 -0
- package/.python-version +1 -0
- package/Dockerfile +15 -0
- package/README.md +3 -0
- package/babel.config.js +3 -0
- package/data-contracts/ABIs/AdminUpgradeabilityProxy.json +132 -0
- package/data-contracts/ABIs/BaseAdminUpgradeabilityProxy.json +113 -0
- package/data-contracts/ABIs/BaseUpgradeabilityProxy.json +22 -0
- package/data-contracts/ABIs/DiscoveryProviderFactory.json +189 -0
- package/data-contracts/ABIs/DiscoveryProviderFactoryInterface.json +61 -0
- package/data-contracts/ABIs/DiscoveryProviderStorage.json +205 -0
- package/data-contracts/ABIs/DiscoveryProviderStorageInterface.json +65 -0
- package/data-contracts/ABIs/ECDSA.json +4 -0
- package/data-contracts/ABIs/IPLDBlacklistFactory.json +168 -0
- package/data-contracts/ABIs/Initializable.json +4 -0
- package/data-contracts/ABIs/Migrations.json +67 -0
- package/data-contracts/ABIs/OpenZeppelinUpgradesAddress.json +4 -0
- package/data-contracts/ABIs/Ownable.json +79 -0
- package/data-contracts/ABIs/PlaylistFactory.json +669 -0
- package/data-contracts/ABIs/PlaylistFactoryInterface.json +42 -0
- package/data-contracts/ABIs/PlaylistStorage.json +250 -0
- package/data-contracts/ABIs/PlaylistStorageInterface.json +129 -0
- package/data-contracts/ABIs/Proxy.json +10 -0
- package/data-contracts/ABIs/Registry.json +240 -0
- package/data-contracts/ABIs/RegistryContract.json +102 -0
- package/data-contracts/ABIs/RegistryContractInterface.json +28 -0
- package/data-contracts/ABIs/RegistryInterface.json +66 -0
- package/data-contracts/ABIs/SigningLogic.json +43 -0
- package/data-contracts/ABIs/SigningLogicInitializable.json +46 -0
- package/data-contracts/ABIs/SocialFeatureFactory.json +460 -0
- package/data-contracts/ABIs/SocialFeatureStorage.json +225 -0
- package/data-contracts/ABIs/SocialFeatureStorageInterface.json +123 -0
- package/data-contracts/ABIs/TestContract.json +135 -0
- package/data-contracts/ABIs/TestContractInterface.json +19 -0
- package/data-contracts/ABIs/TestContractWithStorage.json +165 -0
- package/data-contracts/ABIs/TestContractWithStorageInterface.json +24 -0
- package/data-contracts/ABIs/TestStorage.json +144 -0
- package/data-contracts/ABIs/TestStorageInterface.json +42 -0
- package/data-contracts/ABIs/TestUserReplicaSetManager.json +432 -0
- package/data-contracts/ABIs/TrackFactory.json +391 -0
- package/data-contracts/ABIs/TrackFactoryInterface.json +73 -0
- package/data-contracts/ABIs/TrackStorage.json +223 -0
- package/data-contracts/ABIs/TrackStorageInterface.json +121 -0
- package/data-contracts/ABIs/UpgradeabilityProxy.json +37 -0
- package/data-contracts/ABIs/UserFactory.json +657 -0
- package/data-contracts/ABIs/UserFactoryInterface.json +65 -0
- package/data-contracts/ABIs/UserLibraryFactory.json +334 -0
- package/data-contracts/ABIs/UserReplicaSetManager.json +418 -0
- package/data-contracts/ABIs/UserStorage.json +233 -0
- package/data-contracts/ABIs/UserStorageInterface.json +93 -0
- package/data-contracts/signatureSchemas.ts +1236 -0
- package/dist/core.d.ts +446 -0
- package/dist/core.js +769 -0
- package/dist/core.js.map +1 -0
- package/dist/index.d.ts +689 -0
- package/dist/index.js +72850 -0
- package/dist/index.js.map +1 -0
- package/eth-contracts/ABIs/Address.json +4 -0
- package/eth-contracts/ABIs/AudiusAdminUpgradeabilityProxy.json +105 -0
- package/eth-contracts/ABIs/AudiusClaimDistributor.json +4968 -0
- package/eth-contracts/ABIs/AudiusToken.json +724 -0
- package/eth-contracts/ABIs/BaseUpgradeabilityProxy.json +23 -0
- package/eth-contracts/ABIs/Checkpointing.json +4 -0
- package/eth-contracts/ABIs/ClaimsManager.json +539 -0
- package/eth-contracts/ABIs/Context.json +11 -0
- package/eth-contracts/ABIs/DelegateManager.json +989 -0
- package/eth-contracts/ABIs/DelegateManagerV2.json +1049 -0
- package/eth-contracts/ABIs/DelegateManagerV2Bad.json +1049 -0
- package/eth-contracts/ABIs/ERC20.json +252 -0
- package/eth-contracts/ABIs/ERC20Burnable.json +287 -0
- package/eth-contracts/ABIs/ERC20Detailed.json +270 -0
- package/eth-contracts/ABIs/ERC20Mintable.json +364 -0
- package/eth-contracts/ABIs/ERC20Pausable.json +397 -0
- package/eth-contracts/ABIs/EthRewardsManager.json +174 -0
- package/eth-contracts/ABIs/Governance.json +938 -0
- package/eth-contracts/ABIs/GovernanceUpgraded.json +953 -0
- package/eth-contracts/ABIs/GovernanceV2.json +938 -0
- package/eth-contracts/ABIs/IERC20.json +200 -0
- package/eth-contracts/ABIs/Initializable.json +4 -0
- package/eth-contracts/ABIs/InitializableV2.json +14 -0
- package/eth-contracts/ABIs/Migrations.json +71 -0
- package/eth-contracts/ABIs/MinterRole.json +91 -0
- package/eth-contracts/ABIs/MockAccount.json +62 -0
- package/eth-contracts/ABIs/MockDelegateManager.json +55 -0
- package/eth-contracts/ABIs/MockStakingCaller.json +259 -0
- package/eth-contracts/ABIs/MockWormhole.json +106 -0
- package/eth-contracts/ABIs/OpenZeppelinUpgradesAddress.json +4 -0
- package/eth-contracts/ABIs/Ownable.json +93 -0
- package/eth-contracts/ABIs/Pausable.json +150 -0
- package/eth-contracts/ABIs/PauserRole.json +91 -0
- package/eth-contracts/ABIs/Proxy.json +10 -0
- package/eth-contracts/ABIs/Registry.json +288 -0
- package/eth-contracts/ABIs/Roles.json +4 -0
- package/eth-contracts/ABIs/SafeERC20.json +4 -0
- package/eth-contracts/ABIs/SafeMath.json +4 -0
- package/eth-contracts/ABIs/ServiceProviderFactory.json +1153 -0
- package/eth-contracts/ABIs/ServiceTypeManager.json +337 -0
- package/eth-contracts/ABIs/Staking.json +555 -0
- package/eth-contracts/ABIs/StakingUpgraded.json +570 -0
- package/eth-contracts/ABIs/TestContract.json +44 -0
- package/eth-contracts/ABIs/TrustedNotifierManager.json +265 -0
- package/eth-contracts/ABIs/Uint256Helpers.json +4 -0
- package/eth-contracts/ABIs/UpgradeabilityProxy.json +40 -0
- package/eth-contracts/ABIs/Wormhole.json +45 -0
- package/eth-contracts/ABIs/WormholeClient.json +155 -0
- package/examples/file.mp3 +0 -0
- package/examples/initAudiusLibs.js +86 -0
- package/examples/initializeVersions.js +95 -0
- package/examples/pic.jpg +0 -0
- package/initScripts/configureLocalDiscProv.js +167 -0
- package/initScripts/helpers/claim.js +43 -0
- package/initScripts/helpers/distributeTokens.js +24 -0
- package/initScripts/helpers/spRegistration.js +138 -0
- package/initScripts/helpers/utils.js +34 -0
- package/initScripts/helpers/version.js +93 -0
- package/initScripts/local.js +617 -0
- package/initScripts/mainnet.js +131 -0
- package/initScripts/manageProdRelayerWallets.js +191 -0
- package/package.json +125 -0
- package/rollup.config.js +164 -0
- package/scripts/AudiusClaimDistributor.json +4968 -0
- package/scripts/Wormhole.json +155 -0
- package/scripts/addCIDToIpldBlacklist.js +124 -0
- package/scripts/circleci-test.sh +53 -0
- package/scripts/communityRewards/transferCommunityRewardsToSolana.js +222 -0
- package/scripts/ipfs.sh +58 -0
- package/scripts/migrate_contracts.sh +25 -0
- package/scripts/reset.sh +65 -0
- package/scripts/test.sh +77 -0
- package/src/api/account.js +670 -0
- package/src/api/base.js +122 -0
- package/src/api/file.js +168 -0
- package/src/api/playlist.js +328 -0
- package/src/api/rewards.d.ts +4 -0
- package/src/api/rewards.js +682 -0
- package/src/api/serviceProvider.js +154 -0
- package/src/api/track.js +604 -0
- package/src/api/user.js +888 -0
- package/src/api/user.test.js +172 -0
- package/src/constants.ts +7 -0
- package/src/core.ts +3 -0
- package/src/index.js +6 -0
- package/src/libs.d.ts +3 -0
- package/src/libs.js +619 -0
- package/src/sanityChecks/addSecondaries.js +40 -0
- package/src/sanityChecks/assignReplicaSetIfNecessary.js +10 -0
- package/src/sanityChecks/index.d.ts +9 -0
- package/src/sanityChecks/index.js +31 -0
- package/src/sanityChecks/isCreator.js +73 -0
- package/src/sanityChecks/needsRecoveryEmail.js +20 -0
- package/src/sanityChecks/rolloverNodes.js +74 -0
- package/src/sanityChecks/sanitizeNodes.js +24 -0
- package/src/sanityChecks/syncNodes.js +28 -0
- package/src/sdk/constants.ts +10 -0
- package/src/sdk/index.ts +1 -0
- package/src/sdk/oauth/Oauth.ts +265 -0
- package/src/sdk/oauth/index.ts +1 -0
- package/src/sdk/sdk.ts +102 -0
- package/src/service-selection/ServiceSelection.test.ts +320 -0
- package/src/service-selection/ServiceSelection.ts +460 -0
- package/src/service-selection/constants.ts +14 -0
- package/src/service-selection/index.ts +1 -0
- package/src/services/ABIDecoder/AudiusABIDecoder.ts +71 -0
- package/src/services/ABIDecoder/index.ts +1 -0
- package/src/services/comstock/Comstock.ts +39 -0
- package/src/services/comstock/index.ts +1 -0
- package/src/services/contracts/ContractClient.ts +227 -0
- package/src/services/contracts/GovernedContractClient.ts +53 -0
- package/src/services/contracts/ProviderSelection.ts +42 -0
- package/src/services/creatorNode/CreatorNode.ts +1065 -0
- package/src/services/creatorNode/CreatorNodeSelection.test.ts +997 -0
- package/src/services/creatorNode/CreatorNodeSelection.ts +488 -0
- package/src/services/creatorNode/constants.ts +10 -0
- package/src/services/creatorNode/index.ts +2 -0
- package/src/services/dataContracts/AudiusContracts.ts +234 -0
- package/src/services/dataContracts/IPLDBlacklistFactoryClient.ts +73 -0
- package/src/services/dataContracts/PlaylistFactoryClient.ts +370 -0
- package/src/services/dataContracts/RegistryClient.ts +95 -0
- package/src/services/dataContracts/SocialFeatureFactoryClient.ts +196 -0
- package/src/services/dataContracts/TrackFactoryClient.ts +131 -0
- package/src/services/dataContracts/UserFactoryClient.ts +351 -0
- package/src/services/dataContracts/UserLibraryFactoryClient.ts +115 -0
- package/src/services/dataContracts/UserReplicaSetManagerClient.ts +206 -0
- package/src/services/dataContracts/index.ts +1 -0
- package/src/services/discoveryProvider/DiscoveryProvider.ts +1168 -0
- package/src/services/discoveryProvider/DiscoveryProviderSelection.test.ts +536 -0
- package/src/services/discoveryProvider/DiscoveryProviderSelection.ts +383 -0
- package/src/services/discoveryProvider/constants.ts +13 -0
- package/src/services/discoveryProvider/index.ts +1 -0
- package/src/services/discoveryProvider/requests.ts +629 -0
- package/src/services/ethContracts/AudiusTokenClient.ts +163 -0
- package/src/services/ethContracts/ClaimDistributionClient.ts +45 -0
- package/src/services/ethContracts/ClaimsManagerClient.ts +102 -0
- package/src/services/ethContracts/DelegateManagerClient.ts +480 -0
- package/src/services/ethContracts/EthContracts.ts +359 -0
- package/src/services/ethContracts/EthRewardsManagerClient.ts +33 -0
- package/src/services/ethContracts/GovernanceClient.ts +451 -0
- package/src/services/ethContracts/RegistryClient.ts +33 -0
- package/src/services/ethContracts/ServiceProviderFactoryClient.ts +691 -0
- package/src/services/ethContracts/ServiceTypeManagerClient.ts +112 -0
- package/src/services/ethContracts/StakingProxyClient.ts +97 -0
- package/src/services/ethContracts/TrustedNotifierManagerClient.ts +101 -0
- package/src/services/ethContracts/WormholeClient.ts +97 -0
- package/src/services/ethContracts/index.ts +1 -0
- package/src/services/ethWeb3Manager/EthWeb3Manager.ts +239 -0
- package/src/services/ethWeb3Manager/index.ts +1 -0
- package/src/services/hedgehog/Hedgehog.ts +96 -0
- package/src/services/hedgehog/index.ts +1 -0
- package/src/services/identity/IdentityService.ts +551 -0
- package/src/services/identity/index.ts +1 -0
- package/src/services/identity/requests.ts +65 -0
- package/src/services/schemaValidator/SchemaValidator.ts +105 -0
- package/src/services/schemaValidator/index.ts +1 -0
- package/src/services/schemaValidator/schemas/trackSchema.json +267 -0
- package/src/services/schemaValidator/schemas/userSchema.json +230 -0
- package/src/services/solanaAudiusData/errors.ts +20 -0
- package/src/services/solanaAudiusData/index.ts +1189 -0
- package/src/services/solanaWeb3Manager/errors.js +101 -0
- package/src/services/solanaWeb3Manager/index.d.ts +46 -0
- package/src/services/solanaWeb3Manager/index.js +655 -0
- package/src/services/solanaWeb3Manager/padBNToUint8Array.ts +7 -0
- package/src/services/solanaWeb3Manager/rewards.js +941 -0
- package/src/services/solanaWeb3Manager/rewardsAttester.ts +1093 -0
- package/src/services/solanaWeb3Manager/tokenAccount.js +149 -0
- package/src/services/solanaWeb3Manager/transactionHandler.js +345 -0
- package/src/services/solanaWeb3Manager/transfer.js +272 -0
- package/src/services/solanaWeb3Manager/userBank.js +160 -0
- package/src/services/solanaWeb3Manager/utils.d.ts +31 -0
- package/src/services/solanaWeb3Manager/utils.js +163 -0
- package/src/services/solanaWeb3Manager/wAudio.js +28 -0
- package/src/services/solanaWeb3Manager/wAudio.test.js +30 -0
- package/src/services/web3Manager/Web3Config.ts +14 -0
- package/src/services/web3Manager/Web3Manager.ts +360 -0
- package/src/services/web3Manager/XMLHttpRequest.ts +11 -0
- package/src/services/web3Manager/index.ts +2 -0
- package/src/services/wormhole/index.js +424 -0
- package/src/types.ts +8 -0
- package/src/userStateManager.ts +53 -0
- package/src/utils/apiSigning.ts +51 -0
- package/src/utils/captcha.ts +97 -0
- package/src/utils/estimateGas.ts +64 -0
- package/src/utils/fileHasher.ts +278 -0
- package/src/utils/importContractABI.d.ts +9 -0
- package/src/utils/importContractABI.js +19 -0
- package/src/utils/index.ts +11 -0
- package/src/utils/multiProvider.ts +72 -0
- package/src/utils/network.test.ts +127 -0
- package/src/utils/network.ts +308 -0
- package/src/utils/promiseFight.test.ts +87 -0
- package/src/utils/promiseFight.ts +36 -0
- package/src/utils/signatures.ts +139 -0
- package/src/utils/types.ts +34 -0
- package/src/utils/utils.test.ts +36 -0
- package/src/utils/utils.ts +235 -0
- package/src/utils/uuid.ts +14 -0
- package/src/web3.d.ts +9 -0
- package/src/web3.js +8 -0
- package/tests/assets/static_image.png +0 -0
- package/tests/assets/static_text.txt +1 -0
- package/tests/audiusTokenClientTest.js +37 -0
- package/tests/creatorNodeTest.js +19 -0
- package/tests/fileHasherTest.js +125 -0
- package/tests/governanceTest.js +382 -0
- package/tests/helpers.js +105 -0
- package/tests/index.js +14 -0
- package/tests/playlistClientTest.js +157 -0
- package/tests/providerSelectionTest.js +241 -0
- package/tests/registryClientTest.js +19 -0
- package/tests/rewardsAttesterTest.js +373 -0
- package/tests/serviceTypeManagerClientTest.js +33 -0
- package/tests/socialFeatureClientTest.js +79 -0
- package/tests/stakingTest.js +302 -0
- package/tests/trackClientTest.js +86 -0
- package/tests/userClientTest.js +121 -0
- package/tsconfig.json +10 -0
- package/types/@audius-hedgehog/index.d.ts +39 -0
- package/types/abi-decoder/index.d.ts +41 -0
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Backup,
|
|
3
|
+
Decision,
|
|
4
|
+
ServiceSelection,
|
|
5
|
+
ServiceSelectionConfig
|
|
6
|
+
} from '../../service-selection'
|
|
7
|
+
import {
|
|
8
|
+
DISCOVERY_PROVIDER_TIMESTAMP,
|
|
9
|
+
DISCOVERY_SERVICE_NAME,
|
|
10
|
+
DEFAULT_UNHEALTHY_BLOCK_DIFF,
|
|
11
|
+
DISCOVERY_PROVIDER_RESELECT_TIMEOUT,
|
|
12
|
+
REGRESSED_MODE_TIMEOUT
|
|
13
|
+
} from './constants'
|
|
14
|
+
import semver from 'semver'
|
|
15
|
+
import type { EthContracts } from '../ethContracts'
|
|
16
|
+
import type { AxiosResponse } from 'axios'
|
|
17
|
+
import type { Maybe, Nullable } from '../../utils'
|
|
18
|
+
|
|
19
|
+
const PREVIOUS_VERSIONS_TO_CHECK = 5
|
|
20
|
+
|
|
21
|
+
let localStorage: Storage
|
|
22
|
+
if (typeof window === 'undefined' || window === null) {
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
24
|
+
const LocalStorage = require('node-localstorage').LocalStorage
|
|
25
|
+
localStorage = new LocalStorage('./local-storage')
|
|
26
|
+
} else {
|
|
27
|
+
localStorage = window.localStorage
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type DiscoveryProviderSelectionConfig = Omit<
|
|
31
|
+
ServiceSelectionConfig,
|
|
32
|
+
'getServices'
|
|
33
|
+
> & {
|
|
34
|
+
reselectTimeout?: number
|
|
35
|
+
selectionCallback?: (endpoint: string, decisionTree: Decision[]) => void
|
|
36
|
+
monitoringCallbacks?: {
|
|
37
|
+
healthCheck: (config: Record<string, unknown>) => void
|
|
38
|
+
request: (config: Record<string, unknown>) => void
|
|
39
|
+
}
|
|
40
|
+
unhealthySlotDiffPlays?: number
|
|
41
|
+
unhealthyBlockDiff?: number
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export class DiscoveryProviderSelection extends ServiceSelection {
|
|
45
|
+
currentVersion: string
|
|
46
|
+
ethContracts: EthContracts
|
|
47
|
+
reselectTimeout: Maybe<number>
|
|
48
|
+
selectionCallback: Maybe<
|
|
49
|
+
DiscoveryProviderSelectionConfig['selectionCallback']
|
|
50
|
+
>
|
|
51
|
+
|
|
52
|
+
monitoringCallbacks:
|
|
53
|
+
| NonNullable<DiscoveryProviderSelectionConfig['monitoringCallbacks']>
|
|
54
|
+
| {}
|
|
55
|
+
|
|
56
|
+
unhealthySlotDiffPlays: Nullable<number>
|
|
57
|
+
unhealthyBlockDiff: number
|
|
58
|
+
_regressedMode: boolean
|
|
59
|
+
validVersions: Nullable<string[]>
|
|
60
|
+
|
|
61
|
+
constructor(
|
|
62
|
+
config: DiscoveryProviderSelectionConfig,
|
|
63
|
+
ethContracts: EthContracts
|
|
64
|
+
) {
|
|
65
|
+
super({
|
|
66
|
+
/**
|
|
67
|
+
* Gets the "current" expected service version as well as
|
|
68
|
+
* the list of registered providers from chain
|
|
69
|
+
*/
|
|
70
|
+
getServices: async ({ verbose = false } = {}) => {
|
|
71
|
+
this.currentVersion = await ethContracts.getCurrentVersion(
|
|
72
|
+
DISCOVERY_SERVICE_NAME
|
|
73
|
+
)
|
|
74
|
+
const services = await this.ethContracts.getServiceProviderList(
|
|
75
|
+
DISCOVERY_SERVICE_NAME
|
|
76
|
+
)
|
|
77
|
+
return verbose ? services : services.map((e) => e.endpoint)
|
|
78
|
+
},
|
|
79
|
+
...config
|
|
80
|
+
})
|
|
81
|
+
this.ethContracts = ethContracts
|
|
82
|
+
this.currentVersion = ''
|
|
83
|
+
this.reselectTimeout = config.reselectTimeout
|
|
84
|
+
this.selectionCallback = config.selectionCallback
|
|
85
|
+
this.monitoringCallbacks = config.monitoringCallbacks ?? {}
|
|
86
|
+
this.unhealthySlotDiffPlays = config.unhealthySlotDiffPlays ?? null
|
|
87
|
+
this.unhealthyBlockDiff =
|
|
88
|
+
config.unhealthyBlockDiff ?? DEFAULT_UNHEALTHY_BLOCK_DIFF
|
|
89
|
+
|
|
90
|
+
// Whether or not we are running in `regressed` mode, meaning we were
|
|
91
|
+
// unable to select a discovery provider that was up-to-date. Clients may
|
|
92
|
+
// want to consider blocking writes.
|
|
93
|
+
this._regressedMode = false
|
|
94
|
+
|
|
95
|
+
// List of valid past discovery provider versions registered on chain
|
|
96
|
+
this.validVersions = null
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** Retrieves a cached discovery provider from localstorage */
|
|
100
|
+
getCached() {
|
|
101
|
+
if (localStorage) {
|
|
102
|
+
try {
|
|
103
|
+
const discProvTimestamp = localStorage.getItem(
|
|
104
|
+
DISCOVERY_PROVIDER_TIMESTAMP
|
|
105
|
+
)
|
|
106
|
+
if (discProvTimestamp) {
|
|
107
|
+
const { endpoint: latestEndpoint, timestamp } =
|
|
108
|
+
JSON.parse(discProvTimestamp)
|
|
109
|
+
|
|
110
|
+
const inWhitelist =
|
|
111
|
+
!this.whitelist || this.whitelist.has(latestEndpoint)
|
|
112
|
+
|
|
113
|
+
const timeout = this.reselectTimeout
|
|
114
|
+
? this.reselectTimeout
|
|
115
|
+
: DISCOVERY_PROVIDER_RESELECT_TIMEOUT
|
|
116
|
+
const isExpired = Date.now() - timestamp > timeout
|
|
117
|
+
if (!inWhitelist || isExpired) {
|
|
118
|
+
this.clearCached()
|
|
119
|
+
} else {
|
|
120
|
+
return latestEndpoint
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
} catch (e) {
|
|
124
|
+
console.error(
|
|
125
|
+
'Could not retrieve cached discovery endpoint from localStorage',
|
|
126
|
+
e
|
|
127
|
+
)
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return null
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** Clears any cached discovery provider from localstorage */
|
|
134
|
+
clearCached() {
|
|
135
|
+
if (localStorage) {
|
|
136
|
+
localStorage.removeItem(DISCOVERY_PROVIDER_TIMESTAMP)
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** Sets a cached discovery provider in localstorage */
|
|
141
|
+
setCached(endpoint: string) {
|
|
142
|
+
localStorage.setItem(
|
|
143
|
+
DISCOVERY_PROVIDER_TIMESTAMP,
|
|
144
|
+
JSON.stringify({ endpoint, timestamp: Date.now() })
|
|
145
|
+
)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/** Allows the selection take a shortcut if there's a cached provider */
|
|
149
|
+
override shortcircuit() {
|
|
150
|
+
return this.getCached()
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
override async select() {
|
|
154
|
+
const endpoint = await super.select()
|
|
155
|
+
if (endpoint) {
|
|
156
|
+
this.setCached(endpoint)
|
|
157
|
+
}
|
|
158
|
+
console.info(`Selected discprov ${endpoint}`, this.decisionTree)
|
|
159
|
+
if (this.selectionCallback) {
|
|
160
|
+
this.selectionCallback(endpoint, this.decisionTree)
|
|
161
|
+
}
|
|
162
|
+
return endpoint
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Checks whether a given response is healthy:
|
|
167
|
+
* - Not behind in blocks
|
|
168
|
+
* - 200 response
|
|
169
|
+
* - Current version
|
|
170
|
+
*
|
|
171
|
+
* Other responses are collected in `this.backups` if
|
|
172
|
+
* - Behind by only a patch version
|
|
173
|
+
*
|
|
174
|
+
* @param response axios response
|
|
175
|
+
* @param urlMap health check urls mapped to their cannonical url
|
|
176
|
+
* e.g. https://discoveryprovider.audius.co/health_check => https://discoveryprovider.audius.co
|
|
177
|
+
*/
|
|
178
|
+
override isHealthy(response: AxiosResponse, urlMap: Record<string, string>) {
|
|
179
|
+
const { status, data } = response
|
|
180
|
+
const { block_difference: blockDiff, service, version, plays } = data.data
|
|
181
|
+
let slotDiffPlays = null
|
|
182
|
+
if (plays?.tx_info) {
|
|
183
|
+
slotDiffPlays = plays.tx_info.slot_diff
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if ('healthCheck' in this.monitoringCallbacks) {
|
|
187
|
+
const url = new URL(response.config.url as string)
|
|
188
|
+
try {
|
|
189
|
+
this.monitoringCallbacks.healthCheck({
|
|
190
|
+
endpoint: url.origin,
|
|
191
|
+
pathname: url.pathname,
|
|
192
|
+
queryString: url.search,
|
|
193
|
+
version,
|
|
194
|
+
git: data.data.git,
|
|
195
|
+
blockDifference: blockDiff,
|
|
196
|
+
slotDifferencePlays: slotDiffPlays,
|
|
197
|
+
databaseBlockNumber: data.data.db.number,
|
|
198
|
+
webBlockNumber: data.data.web.blocknumber,
|
|
199
|
+
databaseSize: data.data.database_size,
|
|
200
|
+
databaseConnections: data.data.database_connections,
|
|
201
|
+
totalMemory: data.data.total_memory,
|
|
202
|
+
usedMemory: data.data.used_memory,
|
|
203
|
+
totalStorage: data.data.filesystem_size,
|
|
204
|
+
usedStorage: data.data.filesystem_used,
|
|
205
|
+
receivedBytesPerSec: data.received_bytes_per_sec,
|
|
206
|
+
transferredBytesPerSec: data.transferred_bytes_per_sec,
|
|
207
|
+
challengeLastEventAgeSec: data.challenge_last_event_age_sec
|
|
208
|
+
})
|
|
209
|
+
} catch (e) {
|
|
210
|
+
// Swallow errors -- this method should not throw generally
|
|
211
|
+
console.error(e)
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (status !== 200) return false
|
|
216
|
+
if (service !== DISCOVERY_SERVICE_NAME) return false
|
|
217
|
+
if (!semver.valid(version)) return false
|
|
218
|
+
|
|
219
|
+
// If this service is not the same major/minor as what's on chain, reject
|
|
220
|
+
if (
|
|
221
|
+
!this.ethContracts.hasSameMajorAndMinorVersion(
|
|
222
|
+
this.currentVersion,
|
|
223
|
+
version
|
|
224
|
+
)
|
|
225
|
+
) {
|
|
226
|
+
return false
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// If this service is behind by patches, add it as a backup and reject
|
|
230
|
+
if (semver.patch(version) < semver.patch(this.currentVersion)) {
|
|
231
|
+
this.addBackup(urlMap[response.config.url as string] as string, data.data)
|
|
232
|
+
return false
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// If this service is an unhealthy block diff behind, add it as a backup and reject
|
|
236
|
+
if (blockDiff > this.unhealthyBlockDiff) {
|
|
237
|
+
this.addBackup(urlMap[response.config.url as string] as string, data.data)
|
|
238
|
+
return false
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// If this service is an unhealthy slot diff behind on the plays table, add it
|
|
242
|
+
// as a backup and reject
|
|
243
|
+
if (
|
|
244
|
+
slotDiffPlays !== null &&
|
|
245
|
+
this.unhealthySlotDiffPlays !== null &&
|
|
246
|
+
slotDiffPlays > this.unhealthySlotDiffPlays
|
|
247
|
+
) {
|
|
248
|
+
this.addBackup(urlMap[response.config.url as string] as string, data.data)
|
|
249
|
+
return false
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return true
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Estabilishes that connection to discovery providers has regressed
|
|
257
|
+
*/
|
|
258
|
+
enterRegressedMode() {
|
|
259
|
+
console.info('Entering regressed mode')
|
|
260
|
+
this._regressedMode = true
|
|
261
|
+
setTimeout(() => {
|
|
262
|
+
console.info('Leaving regressed mode')
|
|
263
|
+
this._regressedMode = false
|
|
264
|
+
}, REGRESSED_MODE_TIMEOUT)
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
setUnhealthyBlockDiff(updatedDiff = DEFAULT_UNHEALTHY_BLOCK_DIFF) {
|
|
268
|
+
this.unhealthyBlockDiff = updatedDiff
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
setUnhealthySlotDiffPlays(updatedDiff: number) {
|
|
272
|
+
this.unhealthySlotDiffPlays = updatedDiff
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
isInRegressedMode() {
|
|
276
|
+
return this._regressedMode
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* In the case of no "healthy" services, we resort to backups in the following order:
|
|
281
|
+
* 1. Pick the most recent (patch) version that's not behind
|
|
282
|
+
* 2. Pick the least behind provider that is a valid patch version and enter "regressed mode"
|
|
283
|
+
* 3. Pick `null`
|
|
284
|
+
*/
|
|
285
|
+
override async selectFromBackups() {
|
|
286
|
+
const versions: string[] = []
|
|
287
|
+
const blockDiffs: number[] = []
|
|
288
|
+
|
|
289
|
+
const versionMap: Record<string, string[]> = {}
|
|
290
|
+
const blockDiffMap: Record<string, string[]> = {}
|
|
291
|
+
|
|
292
|
+
// Go backwards in time on chain and get the registered versions up to PREVIOUS_VERSIONS_TO_CHECK.
|
|
293
|
+
// Record those versions in a set and validate any backups against that set.
|
|
294
|
+
// TODO: Clean up this logic when we can validate a specific version rather
|
|
295
|
+
// than traversing backwards through all the versions
|
|
296
|
+
if (!this.validVersions) {
|
|
297
|
+
this.validVersions = [this.currentVersion]
|
|
298
|
+
const numberOfVersions = await this.ethContracts.getNumberOfVersions(
|
|
299
|
+
DISCOVERY_SERVICE_NAME
|
|
300
|
+
)
|
|
301
|
+
for (
|
|
302
|
+
let i = 0;
|
|
303
|
+
i < Math.min(PREVIOUS_VERSIONS_TO_CHECK, numberOfVersions - 1);
|
|
304
|
+
++i
|
|
305
|
+
) {
|
|
306
|
+
const pastServiceVersion = await this.ethContracts.getVersion(
|
|
307
|
+
DISCOVERY_SERVICE_NAME,
|
|
308
|
+
// Exclude the latest version when querying older versions
|
|
309
|
+
// Latest index is numberOfVersions - 1, so 2nd oldest version starts at numberOfVersions - 2
|
|
310
|
+
numberOfVersions - 2 - i
|
|
311
|
+
)
|
|
312
|
+
this.validVersions.push(pastServiceVersion)
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Go through each backup and create two keyed maps:
|
|
317
|
+
// { semver => [provider] }
|
|
318
|
+
// { blockdiff => [provider] }
|
|
319
|
+
Object.keys(this.backups).forEach((backup) => {
|
|
320
|
+
const { block_difference: blockDiff, version } = this.backups[
|
|
321
|
+
backup
|
|
322
|
+
] as Backup
|
|
323
|
+
|
|
324
|
+
let isVersionOk = false
|
|
325
|
+
for (let i = 0; i < (this.validVersions as string[]).length; ++i) {
|
|
326
|
+
if (
|
|
327
|
+
this.ethContracts.hasSameMajorAndMinorVersion(
|
|
328
|
+
this.validVersions?.[i] as string,
|
|
329
|
+
version
|
|
330
|
+
)
|
|
331
|
+
) {
|
|
332
|
+
isVersionOk = true
|
|
333
|
+
break
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
// Filter out any version that wasn't valid given what's registered on chain
|
|
337
|
+
if (!isVersionOk) return
|
|
338
|
+
|
|
339
|
+
versions.push(version)
|
|
340
|
+
blockDiffs.push(blockDiff)
|
|
341
|
+
|
|
342
|
+
if (version in versionMap) {
|
|
343
|
+
versionMap[version]?.push(backup)
|
|
344
|
+
} else {
|
|
345
|
+
versionMap[version] = [backup]
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
if (blockDiff in blockDiffMap) {
|
|
349
|
+
blockDiffMap[blockDiff]?.push(backup)
|
|
350
|
+
} else {
|
|
351
|
+
blockDiffMap[blockDiff] = [backup]
|
|
352
|
+
}
|
|
353
|
+
})
|
|
354
|
+
|
|
355
|
+
// Sort the versions by desc semver
|
|
356
|
+
const sortedVersions = versions.sort(semver.rcompare)
|
|
357
|
+
|
|
358
|
+
// Select the closest version that's a healthy # of blocks behind
|
|
359
|
+
let selected: string = ''
|
|
360
|
+
for (const version of sortedVersions) {
|
|
361
|
+
const endpoints = versionMap[version] as string[]
|
|
362
|
+
for (let i = 0; i < endpoints.length; ++i) {
|
|
363
|
+
if (
|
|
364
|
+
(this.backups[endpoints[i] as string]?.block_difference as number) <
|
|
365
|
+
this.unhealthyBlockDiff
|
|
366
|
+
) {
|
|
367
|
+
selected = endpoints[i] as string
|
|
368
|
+
break
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
if (selected) return selected
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// Select the best block diff provider
|
|
375
|
+
// eslint-disable-next-line @typescript-eslint/require-array-sort-compare
|
|
376
|
+
const bestBlockDiff = blockDiffs.sort()[0] as number
|
|
377
|
+
|
|
378
|
+
selected = blockDiffMap[bestBlockDiff]?.[0] as string
|
|
379
|
+
this.enterRegressedMode()
|
|
380
|
+
|
|
381
|
+
return selected
|
|
382
|
+
}
|
|
383
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const DISCOVERY_PROVIDER_TIMESTAMP =
|
|
2
|
+
'@audius/libs:discovery-node-timestamp'
|
|
3
|
+
export const DISCOVERY_SERVICE_NAME = 'discovery-node'
|
|
4
|
+
export const DEFAULT_UNHEALTHY_BLOCK_DIFF = 15
|
|
5
|
+
export const REGRESSED_MODE_TIMEOUT = 2 * 60 * 1000 // two minutes
|
|
6
|
+
|
|
7
|
+
// When to time out the cached discovery provider
|
|
8
|
+
export const DISCOVERY_PROVIDER_RESELECT_TIMEOUT =
|
|
9
|
+
10 /* min */ * 60 /* seconds */ * 1000 /* millisec */
|
|
10
|
+
// How often to make sure the cached discovery provider is fresh
|
|
11
|
+
export const DISCOVERY_PROVIDER_TIMESTAMP_INTERVAL = 5000
|
|
12
|
+
|
|
13
|
+
export const REQUEST_TIMEOUT_MS = 30 /* seconds */ * 1000 /* millisec */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './DiscoveryProvider'
|