@mainsail/evm-consensus 0.0.1-evm.10

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.
Files changed (35) hide show
  1. package/LICENSE +623 -0
  2. package/README.md +19 -0
  3. package/distribution/deployer.d.ts +10 -0
  4. package/distribution/deployer.d.ts.map +1 -0
  5. package/distribution/deployer.js +236 -0
  6. package/distribution/deployer.js.map +1 -0
  7. package/distribution/identifiers.d.ts +15 -0
  8. package/distribution/identifiers.d.ts.map +1 -0
  9. package/distribution/identifiers.js +15 -0
  10. package/distribution/identifiers.js.map +1 -0
  11. package/distribution/index.d.ts +7 -0
  12. package/distribution/index.d.ts.map +1 -0
  13. package/distribution/index.js +34 -0
  14. package/distribution/index.js.map +1 -0
  15. package/distribution/selector.d.ts +9 -0
  16. package/distribution/selector.d.ts.map +1 -0
  17. package/distribution/selector.js +60 -0
  18. package/distribution/selector.js.map +1 -0
  19. package/distribution/services/consensus-contract-service.d.ts +12 -0
  20. package/distribution/services/consensus-contract-service.d.ts.map +1 -0
  21. package/distribution/services/consensus-contract-service.js +121 -0
  22. package/distribution/services/consensus-contract-service.js.map +1 -0
  23. package/distribution/services/rounds-iterator.d.ts +11 -0
  24. package/distribution/services/rounds-iterator.d.ts.map +1 -0
  25. package/distribution/services/rounds-iterator.js +104 -0
  26. package/distribution/services/rounds-iterator.js.map +1 -0
  27. package/distribution/services/votes-iterator.d.ts +11 -0
  28. package/distribution/services/votes-iterator.d.ts.map +1 -0
  29. package/distribution/services/votes-iterator.js +85 -0
  30. package/distribution/services/votes-iterator.js.map +1 -0
  31. package/distribution/validator-set.d.ts +14 -0
  32. package/distribution/validator-set.d.ts.map +1 -0
  33. package/distribution/validator-set.js +109 -0
  34. package/distribution/validator-set.js.map +1 -0
  35. package/package.json +39 -0
@@ -0,0 +1,104 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
11
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
12
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
13
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
14
+ };
15
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
16
+ if (kind === "m") throw new TypeError("Private method is not writable");
17
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
18
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
19
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
20
+ };
21
+ var _AsyncValidatorRoundsIterator_rounds, _AsyncValidatorRoundsIterator_index, _AsyncValidatorRoundsIterator_offset;
22
+ import { inject, injectable, tagged } from "@mainsail/container";
23
+ import { Contracts, Identifiers } from "@mainsail/contracts";
24
+ import { ConsensusAbi } from "@mainsail/evm-contracts";
25
+ import { Utils } from "@mainsail/kernel";
26
+ import { BigNumber } from "@mainsail/utils";
27
+ import { ethers } from "ethers";
28
+ import { Identifiers as EvmConsensusIdentifiers } from "../identifiers.js";
29
+ const ROUNDS_PER_REQUEST = 10_000;
30
+ let AsyncValidatorRoundsIterator = class AsyncValidatorRoundsIterator {
31
+ constructor() {
32
+ _AsyncValidatorRoundsIterator_rounds.set(this, []);
33
+ _AsyncValidatorRoundsIterator_index.set(this, 0); // Index of returned round in chunk
34
+ _AsyncValidatorRoundsIterator_offset.set(this, 0); // Offset for querying rounds
35
+ }
36
+ [(_AsyncValidatorRoundsIterator_rounds = new WeakMap(), _AsyncValidatorRoundsIterator_index = new WeakMap(), _AsyncValidatorRoundsIterator_offset = new WeakMap(), Symbol.asyncIterator)]() {
37
+ return this;
38
+ }
39
+ async next() {
40
+ var _a, _b;
41
+ if (__classPrivateFieldGet(this, _AsyncValidatorRoundsIterator_rounds, "f").length === __classPrivateFieldGet(this, _AsyncValidatorRoundsIterator_index, "f")) {
42
+ __classPrivateFieldSet(this, _AsyncValidatorRoundsIterator_rounds, await this.getRounds(), "f");
43
+ if (__classPrivateFieldGet(this, _AsyncValidatorRoundsIterator_rounds, "f").length === 0) {
44
+ return { done: true, value: undefined };
45
+ }
46
+ __classPrivateFieldSet(this, _AsyncValidatorRoundsIterator_index, 0, "f");
47
+ __classPrivateFieldSet(this, _AsyncValidatorRoundsIterator_offset, __classPrivateFieldGet(this, _AsyncValidatorRoundsIterator_offset, "f") + __classPrivateFieldGet(this, _AsyncValidatorRoundsIterator_rounds, "f").length, "f");
48
+ }
49
+ return { done: false, value: __classPrivateFieldGet(this, _AsyncValidatorRoundsIterator_rounds, "f")[__classPrivateFieldSet(this, _AsyncValidatorRoundsIterator_index, (_b = __classPrivateFieldGet(this, _AsyncValidatorRoundsIterator_index, "f"), _a = _b++, _b), "f"), _a] };
50
+ }
51
+ async getRounds() {
52
+ const consensusContractAddress = this.app.get(EvmConsensusIdentifiers.Contracts.Addresses.Consensus);
53
+ const deployerAddress = this.app.get(EvmConsensusIdentifiers.Internal.Addresses.Deployer);
54
+ const { evmSpec } = this.configuration.getMilestone();
55
+ const iface = new ethers.Interface(ConsensusAbi.abi);
56
+ const data = iface.encodeFunctionData("getRounds", [__classPrivateFieldGet(this, _AsyncValidatorRoundsIterator_offset, "f"), ROUNDS_PER_REQUEST]).slice(2);
57
+ const result = await this.evm.view({
58
+ caller: deployerAddress,
59
+ data: Buffer.from(data, "hex"),
60
+ recipient: consensusContractAddress,
61
+ specId: evmSpec,
62
+ });
63
+ if (!result.success) {
64
+ await this.app.terminate("getRounds failed");
65
+ }
66
+ const [results] = iface.decodeFunctionResult("getRounds", result.output);
67
+ const validatorRounds = [];
68
+ for (const validatorRound of results) {
69
+ const [round, validators] = validatorRound;
70
+ const roundNumber = Number(round);
71
+ validatorRounds.push({
72
+ round: roundNumber,
73
+ roundHeight: Utils.roundCalculator.calculateRoundInfoByRound(roundNumber, this.configuration)
74
+ .roundHeight,
75
+ validators: validators.map((validator) => {
76
+ const [validatorAddress, voteBalance] = validator;
77
+ return {
78
+ address: validatorAddress,
79
+ voteBalance: BigNumber.make(voteBalance),
80
+ };
81
+ }),
82
+ });
83
+ }
84
+ return validatorRounds;
85
+ }
86
+ };
87
+ __decorate([
88
+ inject(Identifiers.Application.Instance),
89
+ __metadata("design:type", Object)
90
+ ], AsyncValidatorRoundsIterator.prototype, "app", void 0);
91
+ __decorate([
92
+ inject(Identifiers.Cryptography.Configuration),
93
+ __metadata("design:type", Object)
94
+ ], AsyncValidatorRoundsIterator.prototype, "configuration", void 0);
95
+ __decorate([
96
+ inject(Identifiers.Evm.Instance),
97
+ tagged("instance", "evm"),
98
+ __metadata("design:type", Object)
99
+ ], AsyncValidatorRoundsIterator.prototype, "evm", void 0);
100
+ AsyncValidatorRoundsIterator = __decorate([
101
+ injectable()
102
+ ], AsyncValidatorRoundsIterator);
103
+ export { AsyncValidatorRoundsIterator };
104
+ //# sourceMappingURL=rounds-iterator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rounds-iterator.js","sourceRoot":"","sources":["../../source/services/rounds-iterator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { Contracts } from "@mainsail/contracts";
2
+ export declare class AsyncVotesIterator implements AsyncIterable<Contracts.Evm.Vote> {
3
+ #private;
4
+ private readonly app;
5
+ private readonly configuration;
6
+ private readonly evm;
7
+ [Symbol.asyncIterator](): AsyncIterator<Contracts.Evm.Vote>;
8
+ next(): Promise<IteratorResult<Contracts.Evm.Vote>>;
9
+ private getVotes;
10
+ }
11
+ //# sourceMappingURL=votes-iterator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"votes-iterator.d.ts","sourceRoot":"","sources":["../../source/services/votes-iterator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAe,MAAM,qBAAqB,CAAC;AAQ7D,qBACa,kBAAmB,YAAW,aAAa,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;;IAE3E,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAgC;IAGpD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAkC;IAIhE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA0B;IAM9C,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,aAAa,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;IAIrD,IAAI,IAAI,OAAO,CAAC,cAAc,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAe3C,QAAQ;CAuBtB"}
@@ -0,0 +1,85 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
11
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
12
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
13
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
14
+ };
15
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
16
+ if (kind === "m") throw new TypeError("Private method is not writable");
17
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
18
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
19
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
20
+ };
21
+ var _AsyncVotesIterator_address, _AsyncVotesIterator_votes, _AsyncVotesIterator_index;
22
+ import { inject, injectable, tagged } from "@mainsail/container";
23
+ import { Contracts, Identifiers } from "@mainsail/contracts";
24
+ import { ConsensusAbi } from "@mainsail/evm-contracts";
25
+ import { ethers } from "ethers";
26
+ import { Identifiers as EvmConsensusIdentifiers } from "../identifiers.js";
27
+ const VOTES_PER_REQUEST = 10_000;
28
+ let AsyncVotesIterator = class AsyncVotesIterator {
29
+ constructor() {
30
+ _AsyncVotesIterator_address.set(this, "0x0000000000000000000000000000000000000000");
31
+ _AsyncVotesIterator_votes.set(this, []);
32
+ _AsyncVotesIterator_index.set(this, 0);
33
+ }
34
+ [(_AsyncVotesIterator_address = new WeakMap(), _AsyncVotesIterator_votes = new WeakMap(), _AsyncVotesIterator_index = new WeakMap(), Symbol.asyncIterator)]() {
35
+ return this;
36
+ }
37
+ async next() {
38
+ var _a, _b;
39
+ if (__classPrivateFieldGet(this, _AsyncVotesIterator_votes, "f").length === __classPrivateFieldGet(this, _AsyncVotesIterator_index, "f")) {
40
+ __classPrivateFieldSet(this, _AsyncVotesIterator_votes, await this.getVotes(), "f");
41
+ if (__classPrivateFieldGet(this, _AsyncVotesIterator_votes, "f").length === 0) {
42
+ return { done: true, value: undefined };
43
+ }
44
+ __classPrivateFieldSet(this, _AsyncVotesIterator_index, 0, "f");
45
+ __classPrivateFieldSet(this, _AsyncVotesIterator_address, __classPrivateFieldGet(this, _AsyncVotesIterator_votes, "f").at(-1).voterAddress, "f");
46
+ }
47
+ return { done: false, value: __classPrivateFieldGet(this, _AsyncVotesIterator_votes, "f")[__classPrivateFieldSet(this, _AsyncVotesIterator_index, (_b = __classPrivateFieldGet(this, _AsyncVotesIterator_index, "f"), _a = _b++, _b), "f"), _a] };
48
+ }
49
+ async getVotes() {
50
+ const consensusContractAddress = this.app.get(EvmConsensusIdentifiers.Contracts.Addresses.Consensus);
51
+ const deployerAddress = this.app.get(EvmConsensusIdentifiers.Internal.Addresses.Deployer);
52
+ const { evmSpec } = this.configuration.getMilestone();
53
+ const iface = new ethers.Interface(ConsensusAbi.abi);
54
+ const data = iface.encodeFunctionData("getVotes", [__classPrivateFieldGet(this, _AsyncVotesIterator_address, "f"), VOTES_PER_REQUEST]).slice(2);
55
+ const result = await this.evm.view({
56
+ caller: deployerAddress,
57
+ data: Buffer.from(data, "hex"),
58
+ recipient: consensusContractAddress,
59
+ specId: evmSpec,
60
+ });
61
+ if (!result.success) {
62
+ await this.app.terminate("getVotes failed");
63
+ }
64
+ const [votes] = iface.decodeFunctionResult("getVotes", result.output);
65
+ return votes.map((vote) => ({ validatorAddress: vote[1], voterAddress: vote[0] }));
66
+ }
67
+ };
68
+ __decorate([
69
+ inject(Identifiers.Application.Instance),
70
+ __metadata("design:type", Object)
71
+ ], AsyncVotesIterator.prototype, "app", void 0);
72
+ __decorate([
73
+ inject(Identifiers.Cryptography.Configuration),
74
+ __metadata("design:type", Object)
75
+ ], AsyncVotesIterator.prototype, "configuration", void 0);
76
+ __decorate([
77
+ inject(Identifiers.Evm.Instance),
78
+ tagged("instance", "evm"),
79
+ __metadata("design:type", Object)
80
+ ], AsyncVotesIterator.prototype, "evm", void 0);
81
+ AsyncVotesIterator = __decorate([
82
+ injectable()
83
+ ], AsyncVotesIterator);
84
+ export { AsyncVotesIterator };
85
+ //# sourceMappingURL=votes-iterator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"votes-iterator.js","sourceRoot":"","sources":["../../source/services/votes-iterator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { Contracts } from "@mainsail/contracts";
2
+ export declare class ValidatorSet implements Contracts.ValidatorSet.Service {
3
+ #private;
4
+ private readonly configuration;
5
+ private readonly consensusContractService;
6
+ restore(): Promise<void>;
7
+ onCommit(unit: Contracts.Processor.ProcessableUnit): Promise<void>;
8
+ getAllValidators(): Contracts.State.ValidatorWallet[];
9
+ getDirtyValidators(): Contracts.State.ValidatorWallet[];
10
+ getActiveValidators(): Contracts.State.ValidatorWallet[];
11
+ getValidator(index: number): Contracts.State.ValidatorWallet;
12
+ getValidatorIndexByWalletAddress(walletAddress: string): number;
13
+ }
14
+ //# sourceMappingURL=validator-set.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator-set.d.ts","sourceRoot":"","sources":["../source/validator-set.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAA2B,MAAM,qBAAqB,CAAC;AAGzE,qBACa,YAAa,YAAW,SAAS,CAAC,YAAY,CAAC,OAAO;;IAElE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAkC;IAGhE,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAA0C;IAQtE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAOxB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,SAAS,CAAC,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAQxE,gBAAgB,IAAI,SAAS,CAAC,KAAK,CAAC,eAAe,EAAE;IAIrD,kBAAkB,IAAI,SAAS,CAAC,KAAK,CAAC,eAAe,EAAE;IAIvD,mBAAmB,IAAI,SAAS,CAAC,KAAK,CAAC,eAAe,EAAE;IAUxD,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,eAAe;IAI5D,gCAAgC,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM;CAwCtE"}
@@ -0,0 +1,109 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
11
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
12
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
13
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
14
+ };
15
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
16
+ if (kind === "m") throw new TypeError("Private method is not writable");
17
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
18
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
19
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
20
+ };
21
+ var _ValidatorSet_instances, _ValidatorSet_topValidators, _ValidatorSet_indexByAddress, _ValidatorSet_allValidators, _ValidatorSet_dirtyValidators, _ValidatorSet_buildActiveValidators, _ValidatorSet_calculateChangedValidators;
22
+ import { inject, injectable } from "@mainsail/container";
23
+ import { Contracts, Exceptions, Identifiers } from "@mainsail/contracts";
24
+ import { Utils } from "@mainsail/kernel";
25
+ let ValidatorSet = class ValidatorSet {
26
+ constructor() {
27
+ _ValidatorSet_instances.add(this);
28
+ _ValidatorSet_topValidators.set(this, []);
29
+ _ValidatorSet_indexByAddress.set(this, new Map());
30
+ _ValidatorSet_allValidators.set(this, new Map());
31
+ _ValidatorSet_dirtyValidators.set(this, []);
32
+ }
33
+ async restore() {
34
+ await __classPrivateFieldGet(this, _ValidatorSet_instances, "m", _ValidatorSet_buildActiveValidators).call(this);
35
+ const validators = await this.consensusContractService.getAllValidators();
36
+ __classPrivateFieldSet(this, _ValidatorSet_allValidators, new Map(validators.map((validator) => [validator.address, validator])), "f");
37
+ }
38
+ async onCommit(unit) {
39
+ if (Utils.roundCalculator.isNewRound(unit.height + 1, this.configuration)) {
40
+ await __classPrivateFieldGet(this, _ValidatorSet_instances, "m", _ValidatorSet_buildActiveValidators).call(this);
41
+ }
42
+ await __classPrivateFieldGet(this, _ValidatorSet_instances, "m", _ValidatorSet_calculateChangedValidators).call(this);
43
+ }
44
+ getAllValidators() {
45
+ return [...__classPrivateFieldGet(this, _ValidatorSet_allValidators, "f").values()];
46
+ }
47
+ getDirtyValidators() {
48
+ return __classPrivateFieldGet(this, _ValidatorSet_dirtyValidators, "f");
49
+ }
50
+ getActiveValidators() {
51
+ const { activeValidators } = this.configuration.getMilestone();
52
+ if (__classPrivateFieldGet(this, _ValidatorSet_topValidators, "f").length !== activeValidators) {
53
+ throw new Exceptions.NotEnoughActiveValidatorsError(__classPrivateFieldGet(this, _ValidatorSet_topValidators, "f").length, activeValidators);
54
+ }
55
+ return __classPrivateFieldGet(this, _ValidatorSet_topValidators, "f").slice(0, activeValidators);
56
+ }
57
+ getValidator(index) {
58
+ return __classPrivateFieldGet(this, _ValidatorSet_topValidators, "f")[index];
59
+ }
60
+ getValidatorIndexByWalletAddress(walletAddress) {
61
+ const result = __classPrivateFieldGet(this, _ValidatorSet_indexByAddress, "f").get(walletAddress);
62
+ if (result === undefined) {
63
+ throw new Error(`Validator ${walletAddress} not found.`);
64
+ }
65
+ return result;
66
+ }
67
+ };
68
+ _ValidatorSet_topValidators = new WeakMap();
69
+ _ValidatorSet_indexByAddress = new WeakMap();
70
+ _ValidatorSet_allValidators = new WeakMap();
71
+ _ValidatorSet_dirtyValidators = new WeakMap();
72
+ _ValidatorSet_instances = new WeakSet();
73
+ _ValidatorSet_buildActiveValidators = async function _ValidatorSet_buildActiveValidators() {
74
+ const { activeValidators } = this.configuration.getMilestone();
75
+ const validators = await this.consensusContractService.getActiveValidators();
76
+ if (validators.length < activeValidators) {
77
+ throw new Exceptions.NotEnoughActiveValidatorsError(__classPrivateFieldGet(this, _ValidatorSet_topValidators, "f").length, activeValidators);
78
+ }
79
+ __classPrivateFieldSet(this, _ValidatorSet_topValidators, validators.slice(0, activeValidators), "f");
80
+ __classPrivateFieldSet(this, _ValidatorSet_indexByAddress, new Map(__classPrivateFieldGet(this, _ValidatorSet_topValidators, "f").map((validator, index) => [validator.address, index])), "f");
81
+ };
82
+ _ValidatorSet_calculateChangedValidators = async function _ValidatorSet_calculateChangedValidators() {
83
+ __classPrivateFieldSet(this, _ValidatorSet_dirtyValidators, [], "f");
84
+ const validators = await this.consensusContractService.getAllValidators();
85
+ for (const validator of validators) {
86
+ const currentValidator = __classPrivateFieldGet(this, _ValidatorSet_allValidators, "f").get(validator.address);
87
+ if (!currentValidator ||
88
+ !currentValidator.voteBalance.isEqualTo(validator.voteBalance) ||
89
+ currentValidator.isResigned !== validator.isResigned ||
90
+ currentValidator.votersCount !== validator.votersCount ||
91
+ currentValidator.blsPublicKey !== validator.blsPublicKey) {
92
+ __classPrivateFieldGet(this, _ValidatorSet_dirtyValidators, "f").push(validator);
93
+ }
94
+ }
95
+ __classPrivateFieldSet(this, _ValidatorSet_allValidators, new Map(validators.map((validator) => [validator.address, validator])), "f");
96
+ };
97
+ __decorate([
98
+ inject(Identifiers.Cryptography.Configuration),
99
+ __metadata("design:type", Object)
100
+ ], ValidatorSet.prototype, "configuration", void 0);
101
+ __decorate([
102
+ inject(Identifiers.Evm.ContractService.Consensus),
103
+ __metadata("design:type", Object)
104
+ ], ValidatorSet.prototype, "consensusContractService", void 0);
105
+ ValidatorSet = __decorate([
106
+ injectable()
107
+ ], ValidatorSet);
108
+ export { ValidatorSet };
109
+ //# sourceMappingURL=validator-set.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator-set.js","sourceRoot":"","sources":["../source/validator-set.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@mainsail/evm-consensus",
3
+ "version": "0.0.1-evm.10",
4
+ "description": "EVM development support for the Mainsail blockchain",
5
+ "license": "GPL-3.0-only",
6
+ "contributors": [],
7
+ "type": "module",
8
+ "main": "distribution/index.js",
9
+ "types": "distribution/index.d.ts",
10
+ "files": [
11
+ "/distribution"
12
+ ],
13
+ "dependencies": {
14
+ "ethers": "^6.11.0",
15
+ "@mainsail/container": "0.0.1-evm.10",
16
+ "@mainsail/kernel": "0.0.1-evm.10",
17
+ "@mainsail/contracts": "0.0.1-evm.10",
18
+ "@mainsail/evm-contracts": "0.0.1-evm.10",
19
+ "@mainsail/utils": "0.0.1-evm.10"
20
+ },
21
+ "devDependencies": {
22
+ "@types/seedrandom": "^3.0.8",
23
+ "uvu": "^0.5.6"
24
+ },
25
+ "engines": {
26
+ "node": ">=20.x"
27
+ },
28
+ "scripts": {
29
+ "build": "pnpm run clean && tsc",
30
+ "build:watch": "pnpm run clean && tsc -w",
31
+ "clean": "del distribution",
32
+ "release": "pnpm publish --access public",
33
+ "test": "pnpm run uvu source .test.ts",
34
+ "test:coverage": "c8 pnpm run test",
35
+ "test:coverage:html": "c8 -r html --all pnpm run test",
36
+ "test:file": "pnpm run uvu source",
37
+ "uvu": "tsx --tsconfig ../../tsconfig.test.json ./node_modules/uvu/bin.js"
38
+ }
39
+ }