-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathTransactionFlow.ts
More file actions
93 lines (82 loc) · 2.63 KB
/
TransactionFlow.ts
File metadata and controls
93 lines (82 loc) · 2.63 KB
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
import { injectable } from "tsyringe";
import { assertSizeOneOrTwo, dependencyFactory, DependencyRecord } from "@proto-kit/common";
import { Flow, FlowCreator } from "../../../worker/flow/Flow";
import {
RuntimeProof,
TransactionProvingTaskParameters,
} from "../tasks/serializers/types/TransactionProvingTypes";
import { RuntimeProvingTask } from "../tasks/RuntimeProvingTask";
import { TransactionTrace } from "../tracing/TransactionTracingService";
@injectable()
@dependencyFactory()
export class TransactionFlow {
public constructor(
private readonly flowCreator: FlowCreator,
private readonly runtimeProvingTask: RuntimeProvingTask
) {}
public static dependencies(): DependencyRecord {
return {
runtimeProvingTask: {
useClass: RuntimeProvingTask,
},
};
}
private async resolveTransactionFlow(
flow: Flow<{
runtimeProofs: { proof: RuntimeProof; index: number }[];
}>,
trace: [TransactionTrace] | [TransactionTrace, TransactionTrace],
callback: (params: TransactionProvingTaskParameters) => Promise<void>
) {
const requiredLength = trace.length;
if (flow.state.runtimeProofs.length === requiredLength) {
let parameters: TransactionProvingTaskParameters;
if (requiredLength === 2) {
// Sort ascending
const sorted = flow.state.runtimeProofs.sort(
({ index: a }, { index: b }) => a - b
);
parameters = [
{ parameters: trace[0].transaction, proof: sorted[0].proof },
{ parameters: trace[1].transaction, proof: sorted[1].proof },
];
} else {
parameters = [
{
parameters: trace[0].transaction,
proof: flow.state.runtimeProofs[0].proof,
},
];
}
await callback(parameters);
}
}
public async proveRuntimes(
trace: TransactionTrace[],
blockHeight: string,
txIndex: number,
callback: (params: TransactionProvingTaskParameters) => Promise<void>
) {
assertSizeOneOrTwo(trace);
const name = `transaction-${blockHeight}-${txIndex}${
trace.length === 2 ? "-double" : ""
}`;
const flow = this.flowCreator.createFlow<{
runtimeProofs: { proof: RuntimeProof; index: number }[];
}>(name, {
runtimeProofs: [],
});
await Promise.all(
trace.map(async (transaction, index) => {
await flow.pushTask(
this.runtimeProvingTask,
transaction.runtime,
async (proof) => {
flow.state.runtimeProofs.push({ proof, index });
await this.resolveTransactionFlow(flow, trace, callback);
}
);
})
);
}
}