-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathconsensus.ts
More file actions
81 lines (67 loc) · 2.78 KB
/
consensus.ts
File metadata and controls
81 lines (67 loc) · 2.78 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
import type { Types } from "@mainsail/api-common";
import type { Contracts } from "@mainsail/contracts";
import { Identifiers } from "@mainsail/constants";
import { inject, injectable } from "@mainsail/container";
import { Controller } from "./controller.js";
@injectable()
export class ConsensusController extends Controller {
@inject(Identifiers.Consensus.RoundStateRepository)
private readonly roundStateRepository!: Contracts.Consensus.RoundStateRepository;
@inject(Identifiers.ValidatorSet.Service)
private readonly validatorSet!: Contracts.ValidatorSet.Service;
public async state(request: Types.HapiRequest): Promise<object> {
const state = this.app.get<Contracts.Consensus.Service>(Identifiers.Consensus.Service).getState();
const roundStates = this.roundStateRepository.getRoundStates();
const proposals = roundStates
.map((roundState) => roundState.getProposal())
.filter((proposal): proposal is Contracts.Crypto.Proposal => !!proposal);
const prevotes = roundStates.flatMap((roundState) => roundState.getPrevotes());
const precommits = roundStates.flatMap((roundState) => roundState.getPrecommits());
const validators = this.validatorSet.getRoundValidators();
const collectMessages = (messages: ReadonlyArray<Contracts.Crypto.Message>) => {
const collected = {
absent: validators,
};
for (const message of messages) {
const validator = validators[message.validatorIndex];
const key = `b/${message.blockNumber}/${message.round}/${message.blockHash}`;
if (!collected[key]) {
collected[key] = {};
}
const address = validator.address;
collected[key][address] = message.signature;
collected.absent.splice(
collected.absent.findIndex((v) => v.address === address),
1,
);
}
return collected;
};
return {
data: {
blockNumber: state.blockNumber,
lockedValue: state.lockedValue ? state.lockedValue.getProposal()?.blockHeader.hash : null,
prevotes: collectMessages(prevotes.sort((a, b) => b.round - a.round)),
// eslint-disable-next-line perfectionist/sort-objects
lockedRound: state.lockedRound,
proposals: proposals
.sort((a, b) => b.round - a.round)
.map((p) => ({
data: p.toData(),
lockProof: p.lockProof,
name: validators[p.validatorIndex].toString(),
})),
round: state.round,
step: state.step,
// eslint-disable-next-line perfectionist/sort-objects
precommits: collectMessages(precommits.sort((a, b) => b.round - a.round)),
validRound: state.validRound,
validValue: state.validValue ? state.validValue.getProposal()?.blockHeader.hash : null,
// validators: validators.map((v) => ({
// index: this.validatorSet.getValidatorIndexByWalletPublicKey(v.getWalletPublicKey()),
// walletPublicKey: v.toString(),
// })),
},
};
}
}