@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,241 @@
|
|
|
1
|
+
const assert = require('assert')
|
|
2
|
+
const sinon = require('sinon')
|
|
3
|
+
|
|
4
|
+
const { ContractClient } = require('../src/services/contracts/ContractClient')
|
|
5
|
+
const { Web3Manager } = require('../src/services/web3Manager')
|
|
6
|
+
const { EthWeb3Manager } = require('../src/services/ethWeb3Manager')
|
|
7
|
+
|
|
8
|
+
const CONTRACT_INIT_MAX_ATTEMPTS = 5
|
|
9
|
+
|
|
10
|
+
let contractClient
|
|
11
|
+
|
|
12
|
+
describe('Testing ContractClient class with ProviderSelection', () => {
|
|
13
|
+
afterEach(async () => {
|
|
14
|
+
// Reset stub
|
|
15
|
+
sinon.restore()
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Given: audius gateway is healthy
|
|
20
|
+
* When: we do contract logic
|
|
21
|
+
* Should: do not use provider selection logic and use initially set audius gateway
|
|
22
|
+
*/
|
|
23
|
+
it('should use initial audius gateway if healthy', async () => {
|
|
24
|
+
contractClient = createContractClientWithInternalWeb3()
|
|
25
|
+
sinon
|
|
26
|
+
.stub(contractClient.web3Manager.web3.eth, 'Contract')
|
|
27
|
+
.callsFake((arg1, arg2) => {
|
|
28
|
+
return arg1
|
|
29
|
+
})
|
|
30
|
+
const initWithProviderSelectionSpy = sinon.spy(contractClient, 'init')
|
|
31
|
+
const consoleSpy = sinon.spy(console, 'error')
|
|
32
|
+
|
|
33
|
+
await contractClient.init()
|
|
34
|
+
|
|
35
|
+
assert.strictEqual(
|
|
36
|
+
contractClient.web3Manager.getWeb3().currentProvider.host,
|
|
37
|
+
'https://audius.poa.network'
|
|
38
|
+
)
|
|
39
|
+
assert(initWithProviderSelectionSpy.calledOnce)
|
|
40
|
+
assert(consoleSpy.notCalled)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Given: both gatetways are unhealthy
|
|
45
|
+
* When: we do contract logic
|
|
46
|
+
* Should: try both gateways and then log error
|
|
47
|
+
*
|
|
48
|
+
* @notice when web3 is set to a new object, the second call will throw a different error
|
|
49
|
+
* that is acceptable as we don't care about what the error is
|
|
50
|
+
*/
|
|
51
|
+
it('should log error if both audius gateway and public gateway are unhealthy', async () => {
|
|
52
|
+
contractClient = createContractClientWithInternalWeb3()
|
|
53
|
+
sinon
|
|
54
|
+
.stub(contractClient.web3Manager.web3.eth, 'Contract')
|
|
55
|
+
.callsFake((arg1, arg2) => {
|
|
56
|
+
throw new Error('Bad provider')
|
|
57
|
+
})
|
|
58
|
+
const initWithProviderSelectionSpy = sinon.spy(contractClient, 'init')
|
|
59
|
+
const consoleSpy = sinon.spy(console, 'error')
|
|
60
|
+
|
|
61
|
+
await contractClient.init()
|
|
62
|
+
|
|
63
|
+
assert(
|
|
64
|
+
initWithProviderSelectionSpy.callCount === CONTRACT_INIT_MAX_ATTEMPTS
|
|
65
|
+
)
|
|
66
|
+
assert(consoleSpy.callCount === CONTRACT_INIT_MAX_ATTEMPTS)
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Given: contractClient.web3Manager is instanceof ethWeb3Manager
|
|
71
|
+
* When: contract logic passes
|
|
72
|
+
* Should: pass on first try and use initially set gateway
|
|
73
|
+
*/
|
|
74
|
+
it('should use initial gateway url if web3Manager is instanceof ethWeb3Manager and contract logic passes', async () => {
|
|
75
|
+
contractClient = createContractClientWithEthWeb3Manager()
|
|
76
|
+
sinon
|
|
77
|
+
.stub(contractClient.web3Manager.web3.eth, 'Contract')
|
|
78
|
+
.callsFake((arg1, arg2) => {
|
|
79
|
+
return arg1
|
|
80
|
+
})
|
|
81
|
+
const initWithProviderSelectionSpy = sinon.spy(contractClient, 'init')
|
|
82
|
+
const consoleSpy = sinon.spy(console, 'error')
|
|
83
|
+
|
|
84
|
+
await contractClient.init()
|
|
85
|
+
|
|
86
|
+
assert.strictEqual(
|
|
87
|
+
contractClient.web3Manager.getWeb3().currentProvider.host,
|
|
88
|
+
'https://eth.network'
|
|
89
|
+
)
|
|
90
|
+
assert(initWithProviderSelectionSpy.calledOnce)
|
|
91
|
+
assert(consoleSpy.notCalled)
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Given: contractClient.web3Manager is instanceof ethWeb3Manager
|
|
96
|
+
* When: contract logic fails
|
|
97
|
+
* Should: do not do retry logic and log error
|
|
98
|
+
*/
|
|
99
|
+
it('should log error if web3Manager is instanceof ethWeb3Manager and contract logic fails', async () => {
|
|
100
|
+
contractClient = createContractClientWithEthWeb3Manager()
|
|
101
|
+
sinon
|
|
102
|
+
.stub(contractClient.web3Manager.web3.eth, 'Contract')
|
|
103
|
+
.callsFake((arg1, arg2) => {
|
|
104
|
+
throw new Error('Bad provider')
|
|
105
|
+
})
|
|
106
|
+
const initWithProviderSelectionSpy = sinon.spy(contractClient, 'init')
|
|
107
|
+
const consoleSpy = sinon.spy(console, 'error')
|
|
108
|
+
|
|
109
|
+
await contractClient.init()
|
|
110
|
+
|
|
111
|
+
assert.strictEqual(
|
|
112
|
+
contractClient.web3Manager.getWeb3().currentProvider.host,
|
|
113
|
+
'https://eth.network'
|
|
114
|
+
)
|
|
115
|
+
assert(
|
|
116
|
+
initWithProviderSelectionSpy.callCount === CONTRACT_INIT_MAX_ATTEMPTS
|
|
117
|
+
)
|
|
118
|
+
assert(consoleSpy.callCount === CONTRACT_INIT_MAX_ATTEMPTS)
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Given: we are using an external web3
|
|
123
|
+
* When: contract logic passes
|
|
124
|
+
* Should: pass on first try and use initially set gateway
|
|
125
|
+
*/
|
|
126
|
+
it('should use initial gateway url if useExternalWeb3 is true and contract logic passes', async () => {
|
|
127
|
+
contractClient = createContractClientWithExternalWeb3()
|
|
128
|
+
sinon
|
|
129
|
+
.stub(contractClient.web3Manager.web3.eth, 'Contract')
|
|
130
|
+
.callsFake((arg1, arg2) => {
|
|
131
|
+
return arg1
|
|
132
|
+
})
|
|
133
|
+
const initWithProviderSelectionSpy = sinon.spy(contractClient, 'init')
|
|
134
|
+
const consoleSpy = sinon.spy(console, 'error')
|
|
135
|
+
|
|
136
|
+
await contractClient.init()
|
|
137
|
+
|
|
138
|
+
assert.strictEqual(
|
|
139
|
+
contractClient.web3Manager.getWeb3().currentProvider.host,
|
|
140
|
+
'https://audius.poa.network'
|
|
141
|
+
)
|
|
142
|
+
assert(initWithProviderSelectionSpy.calledOnce)
|
|
143
|
+
assert(consoleSpy.notCalled)
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Given: we are using an external web3
|
|
148
|
+
* When: contract logic fails
|
|
149
|
+
* Should: do not do retry logic and log error
|
|
150
|
+
*/
|
|
151
|
+
it('should log error if useExternalWeb3 is true and contract logic fails', async () => {
|
|
152
|
+
contractClient = createContractClientWithExternalWeb3()
|
|
153
|
+
sinon
|
|
154
|
+
.stub(contractClient.web3Manager.web3.eth, 'Contract')
|
|
155
|
+
.callsFake((arg1, arg2) => {
|
|
156
|
+
throw new Error('Bad provider')
|
|
157
|
+
})
|
|
158
|
+
const initWithProviderSelectionSpy = sinon.spy(contractClient, 'init')
|
|
159
|
+
const consoleSpy = sinon.spy(console, 'error')
|
|
160
|
+
|
|
161
|
+
await contractClient.init()
|
|
162
|
+
|
|
163
|
+
assert(
|
|
164
|
+
initWithProviderSelectionSpy.callCount === CONTRACT_INIT_MAX_ATTEMPTS
|
|
165
|
+
)
|
|
166
|
+
assert(consoleSpy.callCount === CONTRACT_INIT_MAX_ATTEMPTS)
|
|
167
|
+
})
|
|
168
|
+
})
|
|
169
|
+
// Helper stub and functions for providerSelectionTest
|
|
170
|
+
|
|
171
|
+
// Available providers
|
|
172
|
+
const gateways = ['https://audius.poa.network', 'https://public.poa.network']
|
|
173
|
+
|
|
174
|
+
// Creates barebones web3 object
|
|
175
|
+
function createWeb3Obj(host) {
|
|
176
|
+
return {
|
|
177
|
+
currentProvider: {
|
|
178
|
+
host
|
|
179
|
+
},
|
|
180
|
+
eth: {
|
|
181
|
+
Contract: () => {}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Helper functions to create ContractClient instances with the appropriate properties
|
|
187
|
+
|
|
188
|
+
function createContractClient(web3Manager) {
|
|
189
|
+
const getRegistryAddressFn = () => {
|
|
190
|
+
return '0xaaaaaaaaaaaaaaaaaaa'
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (web3Manager instanceof Web3Manager) {
|
|
194
|
+
sinon.stub(web3Manager, 'provider').callsFake((arg1, arg2) => {
|
|
195
|
+
return arg1
|
|
196
|
+
})
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return new ContractClient(
|
|
200
|
+
web3Manager,
|
|
201
|
+
'contractABI',
|
|
202
|
+
'contractRegistryKey',
|
|
203
|
+
getRegistryAddressFn
|
|
204
|
+
)
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function createContractClientWithInternalWeb3() {
|
|
208
|
+
const web3Config = {
|
|
209
|
+
useExternalWeb3: false,
|
|
210
|
+
internalWeb3Config: {
|
|
211
|
+
web3ProviderEndpoints: gateways
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
const web3Manager = new Web3Manager()
|
|
215
|
+
web3Manager.web3 = createWeb3Obj('https://audius.poa.network')
|
|
216
|
+
web3Manager.web3Config = web3Config
|
|
217
|
+
return createContractClient(web3Manager)
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function createContractClientWithExternalWeb3() {
|
|
221
|
+
const web3Config = {
|
|
222
|
+
useExternalWeb3: true,
|
|
223
|
+
internalWeb3Config: {
|
|
224
|
+
web3ProviderEndpoints: gateways
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
const web3Manager = new Web3Manager()
|
|
228
|
+
web3Manager.web3 = createWeb3Obj('https://audius.poa.network')
|
|
229
|
+
web3Manager.web3Config = web3Config
|
|
230
|
+
return createContractClient(web3Manager)
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function createContractClientWithEthWeb3Manager() {
|
|
234
|
+
const web3Config = {
|
|
235
|
+
providers: ['https://audius.eth.network'],
|
|
236
|
+
ownerWallet: '0xwallet'
|
|
237
|
+
}
|
|
238
|
+
const ethWeb3Manager = new EthWeb3Manager(web3Config)
|
|
239
|
+
ethWeb3Manager.web3 = createWeb3Obj('https://eth.network')
|
|
240
|
+
return createContractClient(ethWeb3Manager)
|
|
241
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const assert = require('assert')
|
|
2
|
+
let helpers = require('./helpers')
|
|
3
|
+
|
|
4
|
+
let audiusInstance = helpers.audiusInstance
|
|
5
|
+
|
|
6
|
+
before(async function () {
|
|
7
|
+
await audiusInstance.init()
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
it('should call getContract for creatorStorage key', async function () {
|
|
11
|
+
let address = await audiusInstance.contracts.RegistryClient.getContract('creatorStorage')
|
|
12
|
+
assert.notStrictEqual(address, helpers.constants['0x0'])
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
it('should call getContract for nonexistent key', async function () {
|
|
16
|
+
let address = await audiusInstance.contracts.RegistryClient.getContract('nonexistent')
|
|
17
|
+
// not helpers 0x0 because it's not a bytes32 zero value, different number of 0's
|
|
18
|
+
assert.strictEqual(address, '0x0000000000000000000000000000000000000000')
|
|
19
|
+
})
|
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
const assert = require('assert')
|
|
2
|
+
const sinon = require('sinon')
|
|
3
|
+
const {
|
|
4
|
+
AttestationPhases,
|
|
5
|
+
SubmitAndEvaluateError
|
|
6
|
+
} = require('../src/api/rewards')
|
|
7
|
+
const {
|
|
8
|
+
RewardsAttester,
|
|
9
|
+
AttestationDelayCalculator
|
|
10
|
+
} = require('../src/services/solanaWeb3Manager/rewardsAttester')
|
|
11
|
+
const { Utils } = require('../src/utils')
|
|
12
|
+
const { encodeHashId } = Utils
|
|
13
|
+
|
|
14
|
+
function MockLibs(getSlot = () => 100, getBlockNumber = () => 100) {
|
|
15
|
+
this.getSlot = getSlot
|
|
16
|
+
this.getBlockNumber = getBlockNumber
|
|
17
|
+
this.solanaWeb3Manager = {
|
|
18
|
+
getSlot: () => this.getSlot(),
|
|
19
|
+
hasBalance: ({ publicKey }) => true
|
|
20
|
+
}
|
|
21
|
+
this.web3Manager = {
|
|
22
|
+
getWeb3: () => ({
|
|
23
|
+
eth: {
|
|
24
|
+
getBlockNumber: () => this.getBlockNumber()
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
this.Rewards = {
|
|
29
|
+
submitAndEvaluate: (args) => {},
|
|
30
|
+
getUndisbursedChallenges: (args) => {},
|
|
31
|
+
ServiceProvider: {
|
|
32
|
+
getUniquelyOwnedDiscoveryNodes: (quorumSize, nodes) => {
|
|
33
|
+
return nodes.slice(0, quorumSize)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
this.discoveryProvider = {
|
|
38
|
+
serviceSelector: {
|
|
39
|
+
findAll: ({ whitelist }) => {
|
|
40
|
+
return whitelist
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
let calc = null
|
|
47
|
+
|
|
48
|
+
describe('Delay calculator tests', () => {
|
|
49
|
+
afterEach(async () => {
|
|
50
|
+
calc.stop()
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it('Should get Slot and block threshold on fresh start', async () => {
|
|
54
|
+
calc = new AttestationDelayCalculator({
|
|
55
|
+
libs: new MockLibs(
|
|
56
|
+
() => 100,
|
|
57
|
+
() => 100
|
|
58
|
+
),
|
|
59
|
+
runBehindSec: 5,
|
|
60
|
+
allowedStalenessSec: 1
|
|
61
|
+
})
|
|
62
|
+
await calc.start()
|
|
63
|
+
const slotThreshold = await calc.getSolanaSlotThreshold()
|
|
64
|
+
// Should be 90: 100 - 5 / 0.5 block/sec
|
|
65
|
+
assert.strictEqual(slotThreshold, 90)
|
|
66
|
+
|
|
67
|
+
const blockThreshold = await calc.getPOABlockThreshold()
|
|
68
|
+
// Should be 99: 100 - 5 / 5
|
|
69
|
+
assert.strictEqual(blockThreshold, 99)
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
it('Should cache slot and block values', async () => {
|
|
73
|
+
const libs = new MockLibs(
|
|
74
|
+
() => 100,
|
|
75
|
+
() => 100
|
|
76
|
+
)
|
|
77
|
+
calc = new AttestationDelayCalculator({
|
|
78
|
+
libs,
|
|
79
|
+
runBehindSec: 5,
|
|
80
|
+
allowedStalenessSec: 1
|
|
81
|
+
})
|
|
82
|
+
await calc.start()
|
|
83
|
+
await calc.getSolanaSlotThreshold()
|
|
84
|
+
await calc.getPOABlockThreshold()
|
|
85
|
+
|
|
86
|
+
// Test cached values
|
|
87
|
+
libs.getSlot = () => 110
|
|
88
|
+
libs.getBlockNumber = () => 110
|
|
89
|
+
const slotThreshold = await calc.getSolanaSlotThreshold()
|
|
90
|
+
assert.strictEqual(slotThreshold, 90)
|
|
91
|
+
const blockThreshold = await calc.getPOABlockThreshold()
|
|
92
|
+
assert.strictEqual(blockThreshold, 99)
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
it('Should get new values after the cache expires', async () => {
|
|
96
|
+
const libs = new MockLibs(
|
|
97
|
+
() => 100,
|
|
98
|
+
() => 100
|
|
99
|
+
)
|
|
100
|
+
calc = new AttestationDelayCalculator({
|
|
101
|
+
libs,
|
|
102
|
+
runBehindSec: 5,
|
|
103
|
+
allowedStalenessSec: 1
|
|
104
|
+
})
|
|
105
|
+
await calc.start()
|
|
106
|
+
await calc.getSolanaSlotThreshold()
|
|
107
|
+
await calc.getPOABlockThreshold()
|
|
108
|
+
|
|
109
|
+
// Test cached values
|
|
110
|
+
await new Promise((res) => setTimeout(res, 1100))
|
|
111
|
+
libs.getSlot = () => 110
|
|
112
|
+
libs.getBlockNumber = () => 110
|
|
113
|
+
const slotThreshold = await calc.getSolanaSlotThreshold()
|
|
114
|
+
assert.strictEqual(slotThreshold, 100)
|
|
115
|
+
const blockThreshold = await calc.getPOABlockThreshold()
|
|
116
|
+
assert.strictEqual(blockThreshold, 109)
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
it('Should update the solana slot properly', async () => {
|
|
120
|
+
const solSlot = {
|
|
121
|
+
last: 100
|
|
122
|
+
}
|
|
123
|
+
// new slots every 250ms
|
|
124
|
+
const i = setInterval(() => {
|
|
125
|
+
solSlot.last += 1
|
|
126
|
+
}, 250)
|
|
127
|
+
|
|
128
|
+
const libs = new MockLibs(
|
|
129
|
+
() => solSlot.last,
|
|
130
|
+
() => 100
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
calc = new AttestationDelayCalculator({
|
|
134
|
+
libs,
|
|
135
|
+
runBehindSec: 5,
|
|
136
|
+
allowedStalenessSec: 1,
|
|
137
|
+
solanaPollingInterval: 0.5
|
|
138
|
+
})
|
|
139
|
+
calc.start()
|
|
140
|
+
const slotThreshold1 = await calc.getSolanaSlotThreshold()
|
|
141
|
+
// Initially this should be 0.5sec/slot
|
|
142
|
+
assert.strictEqual(slotThreshold1, 90)
|
|
143
|
+
|
|
144
|
+
// Wait for staleness interval
|
|
145
|
+
await new Promise((res) => setTimeout(res, 1100))
|
|
146
|
+
const slotThreshold2 = await calc.getSolanaSlotThreshold()
|
|
147
|
+
// Current slot should be 104, and there should be 4 slots/sec,
|
|
148
|
+
// so 5 sec lag behind = 104 - 5 * 4 = 84
|
|
149
|
+
assert.strictEqual(slotThreshold2, 84)
|
|
150
|
+
|
|
151
|
+
clearInterval(i)
|
|
152
|
+
})
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
describe('Rewards Attester Tests', () => {
|
|
156
|
+
afterEach(async () => {
|
|
157
|
+
sinon.restore()
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
it('Should handle happy path attestation loop', async () => {
|
|
161
|
+
const libs = new MockLibs()
|
|
162
|
+
|
|
163
|
+
const attester = new RewardsAttester({
|
|
164
|
+
libs,
|
|
165
|
+
startingBlock: 0,
|
|
166
|
+
offset: 0,
|
|
167
|
+
parallelization: 2,
|
|
168
|
+
quorumSize: 2,
|
|
169
|
+
aaoEndpoint: 'https://fakeaao.co',
|
|
170
|
+
aaoAddress: '0xFakeOracle',
|
|
171
|
+
challengeIdsDenyList: [],
|
|
172
|
+
endpoints: ['https://dn1.co', 'https://dn2.co', 'https://dn3.co'],
|
|
173
|
+
isSolanaChallenge: () => false,
|
|
174
|
+
feePayerOverride: 'test feepayer override'
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
const rewardsMock = sinon.mock(libs.Rewards)
|
|
178
|
+
|
|
179
|
+
rewardsMock
|
|
180
|
+
.expects('getUndisbursedChallenges')
|
|
181
|
+
.exactly(3)
|
|
182
|
+
.onFirstCall()
|
|
183
|
+
.returns(withSuccess([1, 2].map((i) => makeChallenge(i, i))))
|
|
184
|
+
.onSecondCall()
|
|
185
|
+
.returns(withSuccess([3, 4].map((i) => makeChallenge(i, i))))
|
|
186
|
+
.onThirdCall()
|
|
187
|
+
.callsFake(() => {
|
|
188
|
+
attester.stop()
|
|
189
|
+
return {
|
|
190
|
+
success: []
|
|
191
|
+
}
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
rewardsMock
|
|
195
|
+
.expects('submitAndEvaluate')
|
|
196
|
+
.exactly(4)
|
|
197
|
+
.returns({ success: true })
|
|
198
|
+
|
|
199
|
+
await attester.start()
|
|
200
|
+
assert.equal(attester.startingBlock, 3)
|
|
201
|
+
assert.equal(attester.offset, 0)
|
|
202
|
+
rewardsMock.verify()
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
it('Sets offset correctly for unretryable errors with same starting block', async () => {
|
|
206
|
+
// This tests that we *add* offsets correctly if each challenge we return has the same starting block.
|
|
207
|
+
// For this test, fetch challenges in batches of 2, and the first 4 all share the same completed block
|
|
208
|
+
// and are unretryable, so the offset should be 4 by the end
|
|
209
|
+
const libs = new MockLibs()
|
|
210
|
+
const rewardsStub = sinon.stub(libs.Rewards)
|
|
211
|
+
|
|
212
|
+
const attester = new RewardsAttester({
|
|
213
|
+
libs,
|
|
214
|
+
startingBlock: 0,
|
|
215
|
+
offset: 0,
|
|
216
|
+
parallelization: 2,
|
|
217
|
+
quorumSize: 2,
|
|
218
|
+
aaoEndpoint: 'https://fakeaao.co',
|
|
219
|
+
aaoAddress: '0xFakeOracle',
|
|
220
|
+
challengeIdsDenyList: [],
|
|
221
|
+
endpoints: ['https://dn1.co', 'https://dn2.co', 'https://dn3.co'],
|
|
222
|
+
isSolanaChallenge: () => false,
|
|
223
|
+
feePayerOverride: 'test feepayer override'
|
|
224
|
+
})
|
|
225
|
+
|
|
226
|
+
const [attesterPromise, resolve] = makeAttesterPromise()
|
|
227
|
+
|
|
228
|
+
rewardsStub.getUndisbursedChallenges
|
|
229
|
+
.onFirstCall()
|
|
230
|
+
.returns(withSuccess([0, 1].map((i) => makeChallenge(i, 1))))
|
|
231
|
+
.onSecondCall()
|
|
232
|
+
.returns(withSuccess([2, 3].map((i) => makeChallenge(i, 1))))
|
|
233
|
+
.onThirdCall()
|
|
234
|
+
.callsFake(() => {
|
|
235
|
+
attester.stop()
|
|
236
|
+
resolve()
|
|
237
|
+
return withSuccess([])
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
// Entries 0-3 should return rejection (no retry)
|
|
241
|
+
rewardsStub.submitAndEvaluate
|
|
242
|
+
.withArgs(sinon.match({ specifier: sinon.match.in([0, 1, 2, 3]) }))
|
|
243
|
+
.returns({
|
|
244
|
+
success: false,
|
|
245
|
+
error: SubmitAndEvaluateError.AAO_ATTESTATION_REJECTION,
|
|
246
|
+
phase: AttestationPhases.AGGREGATE_ATTESTATIONS
|
|
247
|
+
})
|
|
248
|
+
|
|
249
|
+
await attester.start()
|
|
250
|
+
await attesterPromise
|
|
251
|
+
|
|
252
|
+
assert.equal(attester.startingBlock, 0)
|
|
253
|
+
assert.equal(attester.offset, 4)
|
|
254
|
+
})
|
|
255
|
+
|
|
256
|
+
it('Sets offset correctly for unretryable errors with different starting block', async () => {
|
|
257
|
+
// If we get some unretryable errors with a different starting block,
|
|
258
|
+
// we should *reset* the offset instead of accumulating it.
|
|
259
|
+
|
|
260
|
+
const libs = new MockLibs()
|
|
261
|
+
const rewardsStub = sinon.stub(libs.Rewards)
|
|
262
|
+
|
|
263
|
+
const attester = new RewardsAttester({
|
|
264
|
+
libs,
|
|
265
|
+
startingBlock: 0,
|
|
266
|
+
offset: 0,
|
|
267
|
+
parallelization: 2,
|
|
268
|
+
quorumSize: 2,
|
|
269
|
+
aaoEndpoint: 'https://fakeaao.co',
|
|
270
|
+
aaoAddress: '0xFakeOracle',
|
|
271
|
+
challengeIdsDenyList: [],
|
|
272
|
+
endpoints: ['https://dn1.co', 'https://dn2.co', 'https://dn3.co'],
|
|
273
|
+
isSolanaChallenge: () => false,
|
|
274
|
+
feePayerOverride: 'test feepayer override'
|
|
275
|
+
})
|
|
276
|
+
|
|
277
|
+
const [attesterPromise, resolve] = makeAttesterPromise()
|
|
278
|
+
|
|
279
|
+
rewardsStub.getUndisbursedChallenges
|
|
280
|
+
.onFirstCall()
|
|
281
|
+
.returns(withSuccess([0, 1].map((i) => makeChallenge(i, 1))))
|
|
282
|
+
.onSecondCall()
|
|
283
|
+
.returns(withSuccess([2, 3].map((i) => makeChallenge(i, 2))))
|
|
284
|
+
.onThirdCall()
|
|
285
|
+
.callsFake(() => {
|
|
286
|
+
attester.stop()
|
|
287
|
+
resolve()
|
|
288
|
+
return withSuccess([])
|
|
289
|
+
})
|
|
290
|
+
|
|
291
|
+
// Entries 0-3 should return rejection (no retry)
|
|
292
|
+
rewardsStub.submitAndEvaluate
|
|
293
|
+
.withArgs(sinon.match({ specifier: sinon.match.in([0, 1, 2, 3]) }))
|
|
294
|
+
.returns({
|
|
295
|
+
success: false,
|
|
296
|
+
error: SubmitAndEvaluateError.AAO_ATTESTATION_REJECTION,
|
|
297
|
+
phase: AttestationPhases.AGGREGATE_ATTESTATIONS
|
|
298
|
+
})
|
|
299
|
+
|
|
300
|
+
await attester.start()
|
|
301
|
+
await attesterPromise
|
|
302
|
+
|
|
303
|
+
assert.equal(attester.startingBlock, 1)
|
|
304
|
+
assert.equal(attester.offset, 2)
|
|
305
|
+
})
|
|
306
|
+
|
|
307
|
+
it('Handles errors in processChallenges after retrying', async () => {
|
|
308
|
+
// processChallenges needs to return an error after it retries and fails,
|
|
309
|
+
// so that clients can act upon the error
|
|
310
|
+
|
|
311
|
+
const libs = new MockLibs()
|
|
312
|
+
const rewardsMock = sinon.mock(libs.Rewards)
|
|
313
|
+
|
|
314
|
+
const attester = new RewardsAttester({
|
|
315
|
+
libs,
|
|
316
|
+
startingBlock: 0,
|
|
317
|
+
offset: 0,
|
|
318
|
+
parallelization: 2,
|
|
319
|
+
quorumSize: 2,
|
|
320
|
+
aaoEndpoint: 'https://fakeaao.co',
|
|
321
|
+
aaoAddress: '0xFakeOracle',
|
|
322
|
+
challengeIdsDenyList: [],
|
|
323
|
+
endpoints: ['https://dn1.co', 'https://dn2.co', 'https://dn3.co'],
|
|
324
|
+
isSolanaChallenge: () => false,
|
|
325
|
+
feePayerOverride: 'test feepayer override',
|
|
326
|
+
maxCooldownMsec: 100
|
|
327
|
+
})
|
|
328
|
+
|
|
329
|
+
// Have it always return a retryable error
|
|
330
|
+
rewardsMock
|
|
331
|
+
.expects("submitAndEvaluate")
|
|
332
|
+
.exactly(5)
|
|
333
|
+
.returns({
|
|
334
|
+
success: false,
|
|
335
|
+
error: SubmitAndEvaluateError.CHALLENGE_INCOMPLETE,
|
|
336
|
+
phase: AttestationPhases.AGGREGATE_ATTESTATIONS
|
|
337
|
+
})
|
|
338
|
+
|
|
339
|
+
const { errors } = await attester.processChallenges([
|
|
340
|
+
{
|
|
341
|
+
challengeId: 'profile-completion',
|
|
342
|
+
userId: encodeHashId(1),
|
|
343
|
+
specifier: '1',
|
|
344
|
+
amount: '1',
|
|
345
|
+
completedBlocknumber: 1,
|
|
346
|
+
handle: 'user_1',
|
|
347
|
+
wallet: '0x1'
|
|
348
|
+
}
|
|
349
|
+
])
|
|
350
|
+
|
|
351
|
+
assert.equal(errors?.length, 1)
|
|
352
|
+
})
|
|
353
|
+
})
|
|
354
|
+
|
|
355
|
+
const makeAttesterPromise = () => {
|
|
356
|
+
let res = null
|
|
357
|
+
const promise = new Promise((resolve) => (res = resolve))
|
|
358
|
+
return [promise, res]
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
const withSuccess = (objs) => ({
|
|
362
|
+
success: objs
|
|
363
|
+
})
|
|
364
|
+
|
|
365
|
+
const makeChallenge = (index, completedBlocknumber) => ({
|
|
366
|
+
challenge_id: 'profile-completion',
|
|
367
|
+
user_id: encodeHashId(index),
|
|
368
|
+
specifier: index,
|
|
369
|
+
amount: '1',
|
|
370
|
+
completed_blocknumber: completedBlocknumber,
|
|
371
|
+
handle: `user_ ${index}`,
|
|
372
|
+
wallet: `0x${index}`
|
|
373
|
+
})
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const assert = require('assert')
|
|
2
|
+
const helpers = require('./helpers')
|
|
3
|
+
|
|
4
|
+
const latestVersionStr = '0.1.0'
|
|
5
|
+
|
|
6
|
+
const audius0 = helpers.audiusInstance
|
|
7
|
+
|
|
8
|
+
let serviceTypeList
|
|
9
|
+
let ownerWallet
|
|
10
|
+
let accounts
|
|
11
|
+
|
|
12
|
+
before(async function () {
|
|
13
|
+
await audius0.init()
|
|
14
|
+
ownerWallet = audius0.ethWeb3Manager.getWalletAddress()
|
|
15
|
+
accounts = await audius0.ethWeb3Manager.getWeb3().eth.getAccounts()
|
|
16
|
+
serviceTypeList = await audius0.ethContracts.ServiceTypeManagerClient.getValidServiceTypes()
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
it('register service versions', async function () {
|
|
20
|
+
for (const serviceType of serviceTypeList) {
|
|
21
|
+
await audius0.ethContracts.ServiceTypeManagerClient.setServiceVersion(
|
|
22
|
+
serviceType,
|
|
23
|
+
latestVersionStr
|
|
24
|
+
)
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it('query service versions', async function () {
|
|
29
|
+
for (const serviceType of serviceTypeList) {
|
|
30
|
+
let currentVersion = await audius0.ethContracts.ServiceTypeManagerClient.getCurrentVersion(serviceType)
|
|
31
|
+
assert(currentVersion === latestVersionStr, 'Expect latest version')
|
|
32
|
+
}
|
|
33
|
+
})
|