@human-protocol/sdk 1.0.1 → 1.0.2
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/package.json +4 -4
- package/src/error.ts +5 -0
- package/src/job.ts +157 -1
- package/src/storage.ts +4 -3
- package/src/types.ts +13 -0
- package/src/utils.ts +67 -1
- package/test/job.test.ts +33 -70
- package/test/utils/constants.ts +3 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@human-protocol/sdk",
|
|
3
3
|
"description": "Human Protocol SDK",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.2",
|
|
5
5
|
"files": [
|
|
6
6
|
"src",
|
|
7
7
|
"dist",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"clean": "rm -rf ./dist",
|
|
15
15
|
"build": "npm run clean && tsc",
|
|
16
16
|
"prepublish": "npm run build",
|
|
17
|
-
"test": "
|
|
17
|
+
"test": "concurrently -k -s first -g --hide 0 \"yarn workspace @human-protocol/core local\" \"sleep 5 && jest --runInBand\"",
|
|
18
18
|
"lint": "eslint .",
|
|
19
19
|
"lint:fix": "eslint . --fix",
|
|
20
20
|
"format": "prettier --write '**/*.{ts,json}'"
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
]
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@human-protocol/core": "^1.0.
|
|
41
|
+
"@human-protocol/core": "^1.0.11",
|
|
42
42
|
"aws-sdk": "^2.1255.0",
|
|
43
43
|
"crypto": "^1.0.1",
|
|
44
44
|
"dotenv": "^16.0.3",
|
|
@@ -47,6 +47,6 @@
|
|
|
47
47
|
"winston": "^3.8.2"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
|
-
"@human-protocol/core": "^1.0.
|
|
50
|
+
"@human-protocol/core": "^1.0.11"
|
|
51
51
|
}
|
|
52
52
|
}
|
package/src/error.ts
CHANGED
|
@@ -36,3 +36,8 @@ export const ErrorHMTokenMissing = new Error('HMToken is missing');
|
|
|
36
36
|
export const ErrorStorageAccessDataMissing = new Error(
|
|
37
37
|
'Storage access data is missing'
|
|
38
38
|
);
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @constant {Error} - The Staking contract is missing.
|
|
42
|
+
*/
|
|
43
|
+
export const ErrorStakingMissing = new Error('Staking contract is missing');
|
package/src/job.ts
CHANGED
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
getEscrow,
|
|
21
21
|
getEscrowFactory,
|
|
22
22
|
getHmToken,
|
|
23
|
+
getStaking,
|
|
23
24
|
toFullDigit,
|
|
24
25
|
} from './utils';
|
|
25
26
|
import {
|
|
@@ -29,6 +30,7 @@ import {
|
|
|
29
30
|
ErrorJobNotLaunched,
|
|
30
31
|
ErrorManifestMissing,
|
|
31
32
|
ErrorReputationOracleMissing,
|
|
33
|
+
ErrorStakingMissing,
|
|
32
34
|
ErrorStorageAccessDataMissing,
|
|
33
35
|
} from './error';
|
|
34
36
|
import { createLogger } from './logger';
|
|
@@ -94,6 +96,7 @@ export class Job {
|
|
|
94
96
|
storageEndpoint,
|
|
95
97
|
storagePublicBucket,
|
|
96
98
|
storageBucket,
|
|
99
|
+
stakingAddr,
|
|
97
100
|
logLevel = 'info',
|
|
98
101
|
}: JobArguments) {
|
|
99
102
|
const provider = network
|
|
@@ -134,6 +137,7 @@ export class Job {
|
|
|
134
137
|
hmTokenAddr,
|
|
135
138
|
escrowAddr,
|
|
136
139
|
factoryAddr,
|
|
140
|
+
stakingAddr,
|
|
137
141
|
};
|
|
138
142
|
|
|
139
143
|
this.manifestData = { manifest };
|
|
@@ -174,9 +178,21 @@ export class Job {
|
|
|
174
178
|
return false;
|
|
175
179
|
}
|
|
176
180
|
|
|
181
|
+
if (!this.contractData.stakingAddr) {
|
|
182
|
+
this._logError(new Error('Staking contract is missing'));
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
this._logger.info('Getting staking...');
|
|
187
|
+
this.contractData.staking = await getStaking(
|
|
188
|
+
this.contractData.stakingAddr,
|
|
189
|
+
this.providerData?.gasPayer
|
|
190
|
+
);
|
|
191
|
+
|
|
177
192
|
this._logger.info('Deploying escrow factory...');
|
|
178
193
|
this.contractData.factory = await deployEscrowFactory(
|
|
179
194
|
this.contractData.hmTokenAddr,
|
|
195
|
+
this.contractData.stakingAddr,
|
|
180
196
|
this.providerData?.gasPayer
|
|
181
197
|
);
|
|
182
198
|
this.contractData.factoryAddr = this.contractData.factory.address;
|
|
@@ -197,6 +213,31 @@ export class Job {
|
|
|
197
213
|
this.providerData?.gasPayer
|
|
198
214
|
);
|
|
199
215
|
|
|
216
|
+
this._logger.info('Checking if staking is configured...');
|
|
217
|
+
const stakingAddr = await this.contractData.factory.staking();
|
|
218
|
+
if (!stakingAddr) {
|
|
219
|
+
this._logError(new Error('Factory is not configured with staking'));
|
|
220
|
+
this.contractData.factory = undefined;
|
|
221
|
+
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
this._logger.info('Getting staking...');
|
|
225
|
+
this.contractData.staking = await getStaking(
|
|
226
|
+
stakingAddr,
|
|
227
|
+
this.providerData?.gasPayer
|
|
228
|
+
);
|
|
229
|
+
this.contractData.stakingAddr = stakingAddr;
|
|
230
|
+
|
|
231
|
+
this._logger.info('Checking if reward pool is configured...');
|
|
232
|
+
const rewardPoolAddr = await this.contractData.staking.rewardPool();
|
|
233
|
+
if (!rewardPoolAddr) {
|
|
234
|
+
this._logError(new Error('Staking is not configured with reward pool'));
|
|
235
|
+
this.contractData.staking = undefined;
|
|
236
|
+
this.contractData.factory = undefined;
|
|
237
|
+
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
|
|
200
241
|
this._logger.info('Checking if escrow exists in the factory...');
|
|
201
242
|
const hasEscrow = await this.contractData?.factory.hasEscrow(
|
|
202
243
|
this.contractData?.escrowAddr
|
|
@@ -283,7 +324,8 @@ export class Job {
|
|
|
283
324
|
const txResponse = await txReceipt?.wait();
|
|
284
325
|
|
|
285
326
|
const event = txResponse?.events?.find(
|
|
286
|
-
|
|
327
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
328
|
+
(event: any) => event.event === 'Launched'
|
|
287
329
|
);
|
|
288
330
|
|
|
289
331
|
const escrowAddr = event?.args?.[1];
|
|
@@ -633,6 +675,120 @@ export class Job {
|
|
|
633
675
|
return (await this.status()) === EscrowStatus.Complete;
|
|
634
676
|
}
|
|
635
677
|
|
|
678
|
+
/**
|
|
679
|
+
* **Stake HMTokens**
|
|
680
|
+
*
|
|
681
|
+
* @param {number} amount - Amount to stake
|
|
682
|
+
* @returns {Promise<boolean>} - True if the token is staked
|
|
683
|
+
*/
|
|
684
|
+
async stake(amount: number) {
|
|
685
|
+
if (!this.contractData?.staking) {
|
|
686
|
+
this._logError(ErrorStakingMissing);
|
|
687
|
+
return false;
|
|
688
|
+
}
|
|
689
|
+
if (!this.contractData.hmToken) {
|
|
690
|
+
this._logError(ErrorHMTokenMissing);
|
|
691
|
+
return false;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
const approved = await this.contractData.hmToken.approve(
|
|
695
|
+
this.contractData.staking.address,
|
|
696
|
+
toFullDigit(amount)
|
|
697
|
+
);
|
|
698
|
+
|
|
699
|
+
if (!approved) {
|
|
700
|
+
this._logError(new Error('Error approving HMTokens for staking'));
|
|
701
|
+
return false;
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
return await this._raffleExecute(
|
|
705
|
+
this.contractData.staking,
|
|
706
|
+
'stake',
|
|
707
|
+
toFullDigit(amount)
|
|
708
|
+
);
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
/**
|
|
712
|
+
* **Unstake HMTokens**
|
|
713
|
+
*
|
|
714
|
+
* @param {number} amount - Amount to unstake
|
|
715
|
+
* @returns {Promise<boolean>} - True if the token is unstaked
|
|
716
|
+
*/
|
|
717
|
+
async unstake(amount: number) {
|
|
718
|
+
if (!this.contractData?.staking) {
|
|
719
|
+
this._logError(ErrorStakingMissing);
|
|
720
|
+
return false;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
return await this._raffleExecute(
|
|
724
|
+
this.contractData.staking,
|
|
725
|
+
'unstake',
|
|
726
|
+
toFullDigit(amount)
|
|
727
|
+
);
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
/**
|
|
731
|
+
* **Withdraw unstaked HMTokens**
|
|
732
|
+
*
|
|
733
|
+
* @returns {Promise<boolean>} - True if the token is withdrawn
|
|
734
|
+
*/
|
|
735
|
+
async withdraw() {
|
|
736
|
+
if (!this.contractData?.staking) {
|
|
737
|
+
this._logError(ErrorStakingMissing);
|
|
738
|
+
return false;
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
return await this._raffleExecute(this.contractData.staking, 'withdraw');
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
/**
|
|
745
|
+
* **Allocate HMTokens staked to the job**
|
|
746
|
+
*
|
|
747
|
+
* @param amount - Amount to allocate
|
|
748
|
+
* @returns {Promise<boolean>} - True if the token is allocated
|
|
749
|
+
*/
|
|
750
|
+
async allocate(amount: number) {
|
|
751
|
+
if (!this.contractData?.staking) {
|
|
752
|
+
this._logError(ErrorStakingMissing);
|
|
753
|
+
return false;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
if (!this.contractData.escrowAddr) {
|
|
757
|
+
this._logError(ErrorJobNotLaunched);
|
|
758
|
+
return false;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
return await this._raffleExecute(
|
|
762
|
+
this.contractData.staking,
|
|
763
|
+
'allocate',
|
|
764
|
+
this.contractData.escrowAddr,
|
|
765
|
+
toFullDigit(amount)
|
|
766
|
+
);
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
/**
|
|
770
|
+
* **Unallocate HMTokens from the job**
|
|
771
|
+
*
|
|
772
|
+
* @returns {Promise<boolean>} - True if the token is unallocated.
|
|
773
|
+
*/
|
|
774
|
+
async closeAllocation() {
|
|
775
|
+
if (!this.contractData?.staking) {
|
|
776
|
+
this._logError(ErrorStakingMissing);
|
|
777
|
+
return false;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
if (!this.contractData.escrowAddr) {
|
|
781
|
+
this._logError(ErrorJobNotLaunched);
|
|
782
|
+
return false;
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
return await this._raffleExecute(
|
|
786
|
+
this.contractData.staking,
|
|
787
|
+
'closeAllocation',
|
|
788
|
+
this.contractData.escrowAddr
|
|
789
|
+
);
|
|
790
|
+
}
|
|
791
|
+
|
|
636
792
|
/**
|
|
637
793
|
* **Get current status of the escrow**
|
|
638
794
|
*
|
package/src/storage.ts
CHANGED
|
@@ -76,7 +76,7 @@ export const getKeyFromURL = (url: string): string => {
|
|
|
76
76
|
* @param {StorageAccessData} storageAccessData - Cloud storage access data
|
|
77
77
|
* @param {string} key - Key of result object
|
|
78
78
|
* @param {string} privateKey - Private key to decode encrypted content
|
|
79
|
-
* @param {
|
|
79
|
+
* @param {boolean} isPublic - Whether the objest is using public bucket, or private bucket
|
|
80
80
|
* @returns {Promise<Result>} - Downloaded result
|
|
81
81
|
*/
|
|
82
82
|
export const download = async (
|
|
@@ -104,14 +104,15 @@ export const download = async (
|
|
|
104
104
|
* @param {StorageAccessData} storageAccessData - Cloud storage access data
|
|
105
105
|
* @param {Result} result - Result to upload
|
|
106
106
|
* @param {string} publicKey - Public key to encrypt data if necessary
|
|
107
|
-
* @param {
|
|
108
|
-
* @param {
|
|
107
|
+
* @param {boolean} _encrypt - Whether to encrypt the result, or not
|
|
108
|
+
* @param {boolean} isPublic - Whether to use public bucket, or private bucket
|
|
109
109
|
* @returns {Promise<UploadResult>} - Uploaded result with key/hash
|
|
110
110
|
*/
|
|
111
111
|
export const upload = async (
|
|
112
112
|
storageAccessData: StorageAccessData,
|
|
113
113
|
result: Result,
|
|
114
114
|
publicKey: string,
|
|
115
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
115
116
|
encrypt = true,
|
|
116
117
|
isPublic = false
|
|
117
118
|
): Promise<UploadResult> => {
|
package/src/types.ts
CHANGED
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
Escrow,
|
|
3
3
|
EscrowFactory,
|
|
4
4
|
HMToken,
|
|
5
|
+
Staking,
|
|
5
6
|
} from '@human-protocol/core/typechain-types';
|
|
6
7
|
import { ethers } from 'ethers';
|
|
7
8
|
|
|
@@ -567,6 +568,14 @@ export type ContractData = {
|
|
|
567
568
|
* HMToken contract instance
|
|
568
569
|
*/
|
|
569
570
|
hmToken?: HMToken;
|
|
571
|
+
/**
|
|
572
|
+
* Staking contract address
|
|
573
|
+
*/
|
|
574
|
+
stakingAddr?: string;
|
|
575
|
+
/**
|
|
576
|
+
* Staking contract instance
|
|
577
|
+
*/
|
|
578
|
+
staking?: Staking;
|
|
570
579
|
};
|
|
571
580
|
|
|
572
581
|
/**
|
|
@@ -627,6 +636,10 @@ export type JobArguments = {
|
|
|
627
636
|
/**
|
|
628
637
|
* Factory contract address
|
|
629
638
|
*/
|
|
639
|
+
stakingAddr?: string;
|
|
640
|
+
/**
|
|
641
|
+
* Staking contract address
|
|
642
|
+
*/
|
|
630
643
|
factoryAddr?: string;
|
|
631
644
|
/**
|
|
632
645
|
* Escrow contract address
|
package/src/utils.ts
CHANGED
|
@@ -7,6 +7,10 @@ import {
|
|
|
7
7
|
EscrowFactory__factory,
|
|
8
8
|
HMToken,
|
|
9
9
|
HMToken__factory,
|
|
10
|
+
Staking,
|
|
11
|
+
Staking__factory,
|
|
12
|
+
RewardPool,
|
|
13
|
+
RewardPool__factory,
|
|
10
14
|
} from '@human-protocol/core/typechain-types';
|
|
11
15
|
|
|
12
16
|
/**
|
|
@@ -31,16 +35,18 @@ export const getHmToken = async (
|
|
|
31
35
|
* **Deploy EscrowFactory contract**
|
|
32
36
|
*
|
|
33
37
|
* @param {string} hmTokenAddr HMToken address
|
|
38
|
+
* @param {string} stakingAddr Staking address
|
|
34
39
|
* @param {ethers.Signer | undefined} signer Deployer signer
|
|
35
40
|
* @returns {Promise<EscrowFactory>} Deployed contract instance
|
|
36
41
|
*/
|
|
37
42
|
export const deployEscrowFactory = async (
|
|
38
43
|
hmTokenAddr: string,
|
|
44
|
+
stakingAddr: string,
|
|
39
45
|
signer?: ethers.Signer
|
|
40
46
|
): Promise<EscrowFactory> => {
|
|
41
47
|
const factory = new EscrowFactory__factory(signer);
|
|
42
48
|
|
|
43
|
-
const contract = await factory.deploy(hmTokenAddr);
|
|
49
|
+
const contract = await factory.deploy(hmTokenAddr, stakingAddr);
|
|
44
50
|
|
|
45
51
|
return contract;
|
|
46
52
|
};
|
|
@@ -81,6 +87,66 @@ export const getEscrow = async (
|
|
|
81
87
|
return contract;
|
|
82
88
|
};
|
|
83
89
|
|
|
90
|
+
/**
|
|
91
|
+
* **Deploy Staking contract**
|
|
92
|
+
*
|
|
93
|
+
* @param {string} hmTokenAddr HMToken address
|
|
94
|
+
* @param {number} minimumStake Minimum amount to stake
|
|
95
|
+
* @param {number} lockPeriod Lock period after unstake
|
|
96
|
+
* @param {ethers.Signer | undefined} signer Deployer signer
|
|
97
|
+
* @returns {Promise<Staking>} Deployed contract instance
|
|
98
|
+
*/
|
|
99
|
+
export const deployStaking = async (
|
|
100
|
+
hmTokenAddr: string,
|
|
101
|
+
minimumStake: number,
|
|
102
|
+
lockPeriod: number,
|
|
103
|
+
signer?: ethers.Signer
|
|
104
|
+
): Promise<Staking> => {
|
|
105
|
+
const staking = new Staking__factory(signer);
|
|
106
|
+
const contract = await staking.deploy(hmTokenAddr, minimumStake, lockPeriod);
|
|
107
|
+
|
|
108
|
+
return contract;
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* **Get Staking contract instance at given address**
|
|
113
|
+
*
|
|
114
|
+
* @param {string} stakingAddr Staking contract address
|
|
115
|
+
* @param {ethers.Signer | undefined} signer Deployer signer
|
|
116
|
+
* @returns {Promise<Staking>} Attached contract instance
|
|
117
|
+
*/
|
|
118
|
+
export const getStaking = async (
|
|
119
|
+
stakingAddr: string,
|
|
120
|
+
signer?: ethers.Signer
|
|
121
|
+
): Promise<Staking> => {
|
|
122
|
+
const factory = new Staking__factory(signer);
|
|
123
|
+
|
|
124
|
+
const contract = await factory.attach(stakingAddr);
|
|
125
|
+
|
|
126
|
+
return contract;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* **Deploy RewardPool contract**
|
|
131
|
+
*
|
|
132
|
+
* @param {string} hmTokenAddr HMToken address
|
|
133
|
+
* @param {string} stakingAddr Staking address
|
|
134
|
+
* @param {number} fee Reward fee of the protocol
|
|
135
|
+
* @param {ethers.Signer | undefined} signer Deployer signer
|
|
136
|
+
* @returns {Promise<Staking>} Deployed contract instance
|
|
137
|
+
*/
|
|
138
|
+
export const deployRewardPool = async (
|
|
139
|
+
hmTokenAddr: string,
|
|
140
|
+
stakingAddr: string,
|
|
141
|
+
fee: number,
|
|
142
|
+
signer?: ethers.Signer
|
|
143
|
+
): Promise<RewardPool> => {
|
|
144
|
+
const rewardPool = new RewardPool__factory(signer);
|
|
145
|
+
const contract = await rewardPool.deploy(hmTokenAddr, stakingAddr, fee);
|
|
146
|
+
|
|
147
|
+
return contract;
|
|
148
|
+
};
|
|
149
|
+
|
|
84
150
|
/**
|
|
85
151
|
* **Get specific amount representation in given decimals**
|
|
86
152
|
*
|
package/test/job.test.ts
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
DEFAULT_GAS_PAYER_ADDR,
|
|
7
7
|
DEFAULT_GAS_PAYER_PRIVKEY,
|
|
8
8
|
DEFAULT_HMTOKEN_ADDR,
|
|
9
|
+
DEFAULT_STAKING_ADDR,
|
|
9
10
|
NOT_TRUSTED_OPERATOR_PRIVKEY,
|
|
10
11
|
REPUTATION_ORACLE_PRIVKEY,
|
|
11
12
|
TRUSTED_OPERATOR1_ADDR,
|
|
@@ -29,6 +30,13 @@ jest.mock('../src/storage', () => ({
|
|
|
29
30
|
getPublicURL: jest.fn().mockResolvedValue('public-url'),
|
|
30
31
|
}));
|
|
31
32
|
|
|
33
|
+
const setupJob = async (job: Job) => {
|
|
34
|
+
await job.initialize();
|
|
35
|
+
await job.stake(1);
|
|
36
|
+
await job.launch();
|
|
37
|
+
await job.setup();
|
|
38
|
+
};
|
|
39
|
+
|
|
32
40
|
describe('Test Job', () => {
|
|
33
41
|
describe('New job', () => {
|
|
34
42
|
let job: Job;
|
|
@@ -39,7 +47,8 @@ describe('Test Job', () => {
|
|
|
39
47
|
reputationOracle: REPUTATION_ORACLE_PRIVKEY,
|
|
40
48
|
manifest: manifest,
|
|
41
49
|
hmTokenAddr: DEFAULT_HMTOKEN_ADDR,
|
|
42
|
-
|
|
50
|
+
stakingAddr: DEFAULT_STAKING_ADDR,
|
|
51
|
+
logLevel: 'error',
|
|
43
52
|
});
|
|
44
53
|
});
|
|
45
54
|
|
|
@@ -54,11 +63,12 @@ describe('Test Job', () => {
|
|
|
54
63
|
expect(await job.contractData?.factory?.address).not.toBeNull();
|
|
55
64
|
});
|
|
56
65
|
|
|
57
|
-
it('Should be able to launch the job', async () => {
|
|
66
|
+
it('Should be able to launch the job after staking', async () => {
|
|
58
67
|
// Fail to launch the job before initialization
|
|
59
68
|
expect(await job.launch()).toBe(false);
|
|
60
69
|
|
|
61
70
|
await job.initialize();
|
|
71
|
+
await job.stake(1);
|
|
62
72
|
|
|
63
73
|
expect(await job.launch()).toBe(true);
|
|
64
74
|
expect(await job.status()).toBe(EscrowStatus.Launched);
|
|
@@ -69,6 +79,8 @@ describe('Test Job', () => {
|
|
|
69
79
|
expect(await job.setup()).toBe(false);
|
|
70
80
|
|
|
71
81
|
await job.initialize();
|
|
82
|
+
await job.stake(1);
|
|
83
|
+
|
|
72
84
|
await job.launch();
|
|
73
85
|
|
|
74
86
|
expect(await job.setup()).toBe(true);
|
|
@@ -76,6 +88,8 @@ describe('Test Job', () => {
|
|
|
76
88
|
|
|
77
89
|
it('Should be able to add trusted handlers', async () => {
|
|
78
90
|
await job.initialize();
|
|
91
|
+
await job.stake(1);
|
|
92
|
+
|
|
79
93
|
await job.launch();
|
|
80
94
|
|
|
81
95
|
expect(await job.isTrustedHandler(DEFAULT_GAS_PAYER_ADDR)).toBe(true);
|
|
@@ -92,9 +106,7 @@ describe('Test Job', () => {
|
|
|
92
106
|
});
|
|
93
107
|
|
|
94
108
|
it('Should be able to bulk payout workers', async () => {
|
|
95
|
-
await job
|
|
96
|
-
await job.launch();
|
|
97
|
-
await job.setup();
|
|
109
|
+
await setupJob(job);
|
|
98
110
|
|
|
99
111
|
expect(
|
|
100
112
|
await job.bulkPayout(
|
|
@@ -148,9 +160,7 @@ describe('Test Job', () => {
|
|
|
148
160
|
});
|
|
149
161
|
|
|
150
162
|
it('Should encrypt result, when bulk paying out workers', async () => {
|
|
151
|
-
await job
|
|
152
|
-
await job.launch();
|
|
153
|
-
await job.setup();
|
|
163
|
+
await setupJob(job);
|
|
154
164
|
|
|
155
165
|
jest.clearAllMocks();
|
|
156
166
|
const finalResults = { results: 0 };
|
|
@@ -176,9 +186,7 @@ describe('Test Job', () => {
|
|
|
176
186
|
});
|
|
177
187
|
|
|
178
188
|
it('Should not encrypt result, when bulk paying out workers', async () => {
|
|
179
|
-
await job
|
|
180
|
-
await job.launch();
|
|
181
|
-
await job.setup();
|
|
189
|
+
await setupJob(job);
|
|
182
190
|
|
|
183
191
|
jest.clearAllMocks();
|
|
184
192
|
const finalResults = { results: 0 };
|
|
@@ -204,9 +212,7 @@ describe('Test Job', () => {
|
|
|
204
212
|
});
|
|
205
213
|
|
|
206
214
|
it('Should store result in private storage, when bulk paying out workers', async () => {
|
|
207
|
-
await job
|
|
208
|
-
await job.launch();
|
|
209
|
-
await job.setup();
|
|
215
|
+
await setupJob(job);
|
|
210
216
|
|
|
211
217
|
jest.clearAllMocks();
|
|
212
218
|
const finalResults = { results: 0 };
|
|
@@ -233,9 +239,7 @@ describe('Test Job', () => {
|
|
|
233
239
|
});
|
|
234
240
|
|
|
235
241
|
it('Should store result in public storage, when bulk paying out workers', async () => {
|
|
236
|
-
await job
|
|
237
|
-
await job.launch();
|
|
238
|
-
await job.setup();
|
|
242
|
+
await setupJob(job);
|
|
239
243
|
|
|
240
244
|
jest.clearAllMocks();
|
|
241
245
|
const finalResults = { results: 0 };
|
|
@@ -263,9 +267,7 @@ describe('Test Job', () => {
|
|
|
263
267
|
});
|
|
264
268
|
|
|
265
269
|
it('Should return final result', async () => {
|
|
266
|
-
await job
|
|
267
|
-
await job.launch();
|
|
268
|
-
await job.setup();
|
|
270
|
+
await setupJob(job);
|
|
269
271
|
|
|
270
272
|
const finalResults = { results: 0 };
|
|
271
273
|
await job.bulkPayout(
|
|
@@ -285,17 +287,13 @@ describe('Test Job', () => {
|
|
|
285
287
|
});
|
|
286
288
|
|
|
287
289
|
it('Should be able to abort the job', async () => {
|
|
288
|
-
await job
|
|
289
|
-
await job.launch();
|
|
290
|
-
await job.setup();
|
|
290
|
+
await setupJob(job);
|
|
291
291
|
|
|
292
292
|
expect(await job.abort()).toBe(true);
|
|
293
293
|
});
|
|
294
294
|
|
|
295
295
|
it('Should be able to abort partially paid job', async () => {
|
|
296
|
-
await job
|
|
297
|
-
await job.launch();
|
|
298
|
-
await job.setup();
|
|
296
|
+
await setupJob(job);
|
|
299
297
|
|
|
300
298
|
const finalResults = { results: 0 };
|
|
301
299
|
await job.bulkPayout(
|
|
@@ -313,9 +311,7 @@ describe('Test Job', () => {
|
|
|
313
311
|
});
|
|
314
312
|
|
|
315
313
|
it('Should not be able to abort fully paid job', async () => {
|
|
316
|
-
await job
|
|
317
|
-
await job.launch();
|
|
318
|
-
await job.setup();
|
|
314
|
+
await setupJob(job);
|
|
319
315
|
|
|
320
316
|
const finalResults = { results: 0 };
|
|
321
317
|
await job.bulkPayout(
|
|
@@ -333,18 +329,14 @@ describe('Test Job', () => {
|
|
|
333
329
|
});
|
|
334
330
|
|
|
335
331
|
it('Should be able to cancel the job', async () => {
|
|
336
|
-
await job
|
|
337
|
-
await job.launch();
|
|
338
|
-
await job.setup();
|
|
332
|
+
await setupJob(job);
|
|
339
333
|
|
|
340
334
|
expect(await job.cancel()).toBe(true);
|
|
341
335
|
expect((await job.balance())?.toString()).toBe(toFullDigit(0).toString());
|
|
342
336
|
});
|
|
343
337
|
|
|
344
338
|
it('Should be able to cancel partially paid job', async () => {
|
|
345
|
-
await job
|
|
346
|
-
await job.launch();
|
|
347
|
-
await job.setup();
|
|
339
|
+
await setupJob(job);
|
|
348
340
|
|
|
349
341
|
const finalResults = { results: 0 };
|
|
350
342
|
await job.bulkPayout(
|
|
@@ -363,9 +355,7 @@ describe('Test Job', () => {
|
|
|
363
355
|
});
|
|
364
356
|
|
|
365
357
|
it('Should not be able to cancel paid job', async () => {
|
|
366
|
-
await job
|
|
367
|
-
await job.launch();
|
|
368
|
-
await job.setup();
|
|
358
|
+
await setupJob(job);
|
|
369
359
|
|
|
370
360
|
const finalResults = { results: 0 };
|
|
371
361
|
await job.bulkPayout(
|
|
@@ -392,13 +382,12 @@ describe('Test Job', () => {
|
|
|
392
382
|
reputationOracle: REPUTATION_ORACLE_PRIVKEY,
|
|
393
383
|
manifest: manifest,
|
|
394
384
|
hmTokenAddr: DEFAULT_HMTOKEN_ADDR,
|
|
385
|
+
stakingAddr: DEFAULT_STAKING_ADDR,
|
|
395
386
|
trustedHandlers: [TRUSTED_OPERATOR1_PRIVKEY],
|
|
396
387
|
logLevel: 'error',
|
|
397
388
|
});
|
|
398
389
|
|
|
399
|
-
await originalJob
|
|
400
|
-
await originalJob.launch();
|
|
401
|
-
await originalJob.setup();
|
|
390
|
+
await setupJob(originalJob);
|
|
402
391
|
|
|
403
392
|
job = new Job({
|
|
404
393
|
gasPayer: NOT_TRUSTED_OPERATOR_PRIVKEY,
|
|
@@ -407,7 +396,7 @@ describe('Test Job', () => {
|
|
|
407
396
|
escrowAddr: originalJob.contractData?.escrowAddr,
|
|
408
397
|
factoryAddr: originalJob.contractData?.factoryAddr,
|
|
409
398
|
trustedHandlers: [TRUSTED_OPERATOR1_PRIVKEY],
|
|
410
|
-
logLevel: '
|
|
399
|
+
logLevel: 'error',
|
|
411
400
|
});
|
|
412
401
|
});
|
|
413
402
|
|
|
@@ -416,8 +405,7 @@ describe('Test Job', () => {
|
|
|
416
405
|
});
|
|
417
406
|
|
|
418
407
|
it('Should be able to initializes the job by accessing existing escrow', async () => {
|
|
419
|
-
|
|
420
|
-
expect(initialized).toBe(true);
|
|
408
|
+
expect(await job.initialize()).toBe(true);
|
|
421
409
|
|
|
422
410
|
expect(await job.manifestData?.manifestlink?.url).toBe('uploaded-key');
|
|
423
411
|
expect(await job.manifestData?.manifestlink?.hash).toBe('uploaded-hash');
|
|
@@ -430,7 +418,7 @@ describe('Test Job', () => {
|
|
|
430
418
|
expect(await job.status()).toBe(EscrowStatus.Pending);
|
|
431
419
|
});
|
|
432
420
|
|
|
433
|
-
it('Should be able to setup the job again', async () => {
|
|
421
|
+
it('Should not be able to setup the job again', async () => {
|
|
434
422
|
await job.initialize();
|
|
435
423
|
|
|
436
424
|
expect(await job.setup()).toBe(false);
|
|
@@ -444,7 +432,6 @@ describe('Test Job', () => {
|
|
|
444
432
|
|
|
445
433
|
it('Should be able to add trusted handlers', async () => {
|
|
446
434
|
await job.initialize();
|
|
447
|
-
await job.launch();
|
|
448
435
|
|
|
449
436
|
expect(await job.isTrustedHandler(DEFAULT_GAS_PAYER_ADDR)).toBe(true);
|
|
450
437
|
|
|
@@ -461,8 +448,6 @@ describe('Test Job', () => {
|
|
|
461
448
|
|
|
462
449
|
it('Should be able to bulk payout workers', async () => {
|
|
463
450
|
await job.initialize();
|
|
464
|
-
await job.launch();
|
|
465
|
-
await job.setup();
|
|
466
451
|
|
|
467
452
|
expect(
|
|
468
453
|
await job.bulkPayout(
|
|
@@ -517,8 +502,6 @@ describe('Test Job', () => {
|
|
|
517
502
|
|
|
518
503
|
it('Should encrypt result, when bulk paying out workers', async () => {
|
|
519
504
|
await job.initialize();
|
|
520
|
-
await job.launch();
|
|
521
|
-
await job.setup();
|
|
522
505
|
|
|
523
506
|
jest.clearAllMocks();
|
|
524
507
|
const finalResults = { results: 0 };
|
|
@@ -545,8 +528,6 @@ describe('Test Job', () => {
|
|
|
545
528
|
|
|
546
529
|
it('Should not encrypt result, when bulk paying out workers', async () => {
|
|
547
530
|
await job.initialize();
|
|
548
|
-
await job.launch();
|
|
549
|
-
await job.setup();
|
|
550
531
|
|
|
551
532
|
jest.clearAllMocks();
|
|
552
533
|
const finalResults = { results: 0 };
|
|
@@ -573,8 +554,6 @@ describe('Test Job', () => {
|
|
|
573
554
|
|
|
574
555
|
it('Should store result in private storage, when bulk paying out workers', async () => {
|
|
575
556
|
await job.initialize();
|
|
576
|
-
await job.launch();
|
|
577
|
-
await job.setup();
|
|
578
557
|
|
|
579
558
|
jest.clearAllMocks();
|
|
580
559
|
const finalResults = { results: 0 };
|
|
@@ -602,8 +581,6 @@ describe('Test Job', () => {
|
|
|
602
581
|
|
|
603
582
|
it('Should store result in public storage, when bulk paying out workers', async () => {
|
|
604
583
|
await job.initialize();
|
|
605
|
-
await job.launch();
|
|
606
|
-
await job.setup();
|
|
607
584
|
|
|
608
585
|
jest.clearAllMocks();
|
|
609
586
|
const finalResults = { results: 0 };
|
|
@@ -632,8 +609,6 @@ describe('Test Job', () => {
|
|
|
632
609
|
|
|
633
610
|
it('Should return final result', async () => {
|
|
634
611
|
await job.initialize();
|
|
635
|
-
await job.launch();
|
|
636
|
-
await job.setup();
|
|
637
612
|
|
|
638
613
|
const finalResults = { results: 0 };
|
|
639
614
|
await job.bulkPayout(
|
|
@@ -654,16 +629,12 @@ describe('Test Job', () => {
|
|
|
654
629
|
|
|
655
630
|
it('Should be able to abort the job', async () => {
|
|
656
631
|
await job.initialize();
|
|
657
|
-
await job.launch();
|
|
658
|
-
await job.setup();
|
|
659
632
|
|
|
660
633
|
expect(await job.abort()).toBe(true);
|
|
661
634
|
});
|
|
662
635
|
|
|
663
636
|
it('Should be able to abort partially paid job', async () => {
|
|
664
637
|
await job.initialize();
|
|
665
|
-
await job.launch();
|
|
666
|
-
await job.setup();
|
|
667
638
|
|
|
668
639
|
const finalResults = { results: 0 };
|
|
669
640
|
await job.bulkPayout(
|
|
@@ -682,8 +653,6 @@ describe('Test Job', () => {
|
|
|
682
653
|
|
|
683
654
|
it('Should not be able to abort fully paid job', async () => {
|
|
684
655
|
await job.initialize();
|
|
685
|
-
await job.launch();
|
|
686
|
-
await job.setup();
|
|
687
656
|
|
|
688
657
|
const finalResults = { results: 0 };
|
|
689
658
|
await job.bulkPayout(
|
|
@@ -702,8 +671,6 @@ describe('Test Job', () => {
|
|
|
702
671
|
|
|
703
672
|
it('Should be able to cancel the job', async () => {
|
|
704
673
|
await job.initialize();
|
|
705
|
-
await job.launch();
|
|
706
|
-
await job.setup();
|
|
707
674
|
|
|
708
675
|
expect(await job.cancel()).toBe(true);
|
|
709
676
|
expect((await job.balance())?.toString()).toBe(toFullDigit(0).toString());
|
|
@@ -711,8 +678,6 @@ describe('Test Job', () => {
|
|
|
711
678
|
|
|
712
679
|
it('Should be able to cancel partially paid job', async () => {
|
|
713
680
|
await job.initialize();
|
|
714
|
-
await job.launch();
|
|
715
|
-
await job.setup();
|
|
716
681
|
|
|
717
682
|
const finalResults = { results: 0 };
|
|
718
683
|
await job.bulkPayout(
|
|
@@ -732,8 +697,6 @@ describe('Test Job', () => {
|
|
|
732
697
|
|
|
733
698
|
it('Should not be able to cancel paid job', async () => {
|
|
734
699
|
await job.initialize();
|
|
735
|
-
await job.launch();
|
|
736
|
-
await job.setup();
|
|
737
700
|
|
|
738
701
|
const finalResults = { results: 0 };
|
|
739
702
|
await job.bulkPayout(
|
package/test/utils/constants.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export const DEFAULT_HMTOKEN_ADDR =
|
|
2
2
|
'0x5FbDB2315678afecb367f032d93F642f64180aa3';
|
|
3
3
|
|
|
4
|
+
export const DEFAULT_STAKING_ADDR =
|
|
5
|
+
'0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512';
|
|
6
|
+
|
|
4
7
|
export const DEFAULT_GAS_PAYER_ADDR =
|
|
5
8
|
'0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266';
|
|
6
9
|
export const DEFAULT_GAS_PAYER_PRIVKEY =
|