-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtaskManager.ts
183 lines (167 loc) · 6.27 KB
/
taskManager.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
import { loadFixture } from "@nomicfoundation/hardhat-toolbox/network-helpers";
import { expect } from "chai";
import hre, { ethers } from "hardhat";
import {
TaskManager,
TaskManager__factory,
TaskOracle,
TaskOracle__factory,
} from "../typechain";
import { TaskType } from "../helpers/configs";
describe("Test Task Manager and Task Oracle", function () {
async function deploy() {
const [owner, submitter, verifierOne, verifierTwo, verifierThree] =
await hre.ethers.getSigners();
const TaskManager = await hre.ethers.getContractFactory("TaskManager");
const TaskManagerImplDeployment = await TaskManager.deploy();
const taskManagerInitData =
TaskManager__factory.createInterface().encodeFunctionData("initialize");
const Proxy = await hre.ethers.getContractFactory(
"TransparentUpgradeableProxy"
);
const TaskManagerProxyDeployment = await Proxy.deploy(
await TaskManagerImplDeployment.getAddress(),
owner.address,
taskManagerInitData
);
let taskManager = TaskManager__factory.connect(
await TaskManagerProxyDeployment.getAddress(),
owner
) as TaskManager;
const TaskOracle = await hre.ethers.getContractFactory("TaskOracle");
const TaskOracleImplDeployment = await TaskOracle.deploy();
const taskOracleInitData =
TaskOracle__factory.createInterface().encodeFunctionData("initialize", [
await taskManager.getAddress(),
]);
const TaskOracleProxyDeployment = await Proxy.deploy(
await TaskOracleImplDeployment.getAddress(),
owner.address,
taskOracleInitData
);
const taskOracle = TaskOracle__factory.connect(
await TaskOracleProxyDeployment.getAddress(),
owner
) as TaskOracle;
await taskManager.setOracle(await taskOracle.getAddress());
await taskManager.addSubmitter(submitter.address);
taskManager = taskManager.connect(submitter);
await taskOracle.addVerifier(verifierOne.address);
await taskOracle.addVerifier(verifierTwo.address);
await taskOracle.addVerifier(verifierThree.address);
await taskOracle.setVerifyThreshold(3);
return {
taskManager,
taskOracle,
submitter,
verifierOne,
verifierTwo,
verifierThree,
};
}
it("Basic check", async () => {
const {
taskManager,
taskOracle,
submitter,
verifierOne,
verifierTwo,
verifierThree,
} = await loadFixture(deploy);
expect(await taskManager.oracle()).to.be.eq(await taskOracle.getAddress());
expect(await taskManager.submitters(submitter.address)).to.be.true;
expect(await taskOracle.taskManager()).to.be.eq(
await taskManager.getAddress()
);
expect(await taskOracle.verifiers(verifierOne.address)).to.be.true;
expect(await taskOracle.verifiers(verifierTwo.address)).to.be.true;
expect(await taskOracle.verifiers(verifierThree.address)).to.be.true;
});
it("Integration Test", async () => {
const {
taskManager,
taskOracle,
submitter,
verifierOne,
verifierTwo,
verifierThree,
} = await loadFixture(deploy);
// Task: fetch Ton token price from pyth
const url =
"https://hermes.pyth.network/v2/updates/price/latest?ids[]=8963217838ab4cf5cadc172203c1f0b763fbaa45f346d8ee50ba994bbcac3026";
const hash = await taskManager.getTaskHash(
submitter.address,
TaskType.HTTP_CALL,
ethers.toUtf8Bytes(url)
);
// submitTask function emit the `SubmitTask` event
await expect(
taskManager.submitTask(TaskType.HTTP_CALL, ethers.toUtf8Bytes(url))
)
.to.emit(taskManager, "SubmitTask")
.withArgs(submitter.address, hash);
const task = await taskManager.tasks(hash);
expect(task.submitter).to.be.eq(submitter.address);
expect(ethers.toUtf8String(task.input)).to.eq(url);
// verifierOne subscribes the `SubmitTask` event of taskManager
// and parse the input according to the taskType
// and handle the request offline
const taskUrl = ethers.toUtf8String(task.input);
const result = (await (await fetch(taskUrl)).json()).parsed[0].price.price;
// verifierOne submits the result to oracle, and wait for the other verifiers to verify
await expect(
taskOracle
.connect(verifierOne)
.verifyTask(hash, ethers.toUtf8Bytes(result), true)
)
.to.emit(taskOracle, "VerifyTask")
.withArgs(hash, verifierOne.address, true);
// All verifiers subscribe the `SubmitTask` event of taskManager and `VerifyTask` event of taskOracle in the same time
// once the result of one task has been submitted to the oracle, other verifiers stop the calculation for the same task,
// and start to verify the submiited result
const taskResult = await taskOracle.taskResults(hash);
// const taskInfo = await taskManager.tasks(hash)
// const taskUrl = ethers.toUtf8String(task.input);
const resultTwo = (await (await fetch(taskUrl)).json()).parsed[0].price
.price;
// verifierTwo check the onchain result
if (
Math.abs(Number(ethers.toUtf8String(taskResult.output)) - resultTwo) /
resultTwo <
0.01
) {
// verifierTwo verify the onchain result as success
await expect(
taskOracle
.connect(verifierTwo)
.verifyTask(hash, taskResult.output, true)
)
.to.emit(taskOracle, "VerifyTask")
.withArgs(hash, verifierTwo.address, true);
console.log("verifierTwo pass");
}
// verifierThree check the onchain result
const resultThree = (await (await fetch(taskUrl)).json()).parsed[0].price
.price;
if (
Math.abs(Number(ethers.toUtf8String(taskResult.output)) - resultThree) /
resultThree <
0.01
) {
// verifierThree verify the onchain result as success
await expect(
taskOracle
.connect(verifierThree)
.verifyTask(hash, taskResult.output, true)
)
.to.emit(taskOracle, "VerifyTask")
.withArgs(hash, verifierThree.address, true)
// verify success and submit the result from oracle to taskManager
.to.emit(taskManager, "VerifyTaskResult")
.withArgs(hash);
console.log("verifierThree pass");
}
const finalTask = await taskManager.tasks(hash);
console.log(Number(ethers.toUtf8String(finalTask.output)));
});
});