@mainsail/consensus 0.0.1-evm.9 → 0.0.1-rc.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/distribution/aggregator.d.ts +2 -3
- package/distribution/aggregator.d.ts.map +1 -1
- package/distribution/aggregator.js +6 -6
- package/distribution/aggregator.js.map +1 -1
- package/distribution/bootstrapper.js +5 -5
- package/distribution/bootstrapper.js.map +1 -1
- package/distribution/commit-state.d.ts +1 -2
- package/distribution/commit-state.d.ts.map +1 -1
- package/distribution/commit-state.js +3 -6
- package/distribution/commit-state.js.map +1 -1
- package/distribution/consensus.d.ts +4 -4
- package/distribution/consensus.d.ts.map +1 -1
- package/distribution/consensus.js +66 -64
- package/distribution/consensus.js.map +1 -1
- package/distribution/index.d.ts.map +1 -1
- package/distribution/index.js +17 -5
- package/distribution/index.js.map +1 -1
- package/distribution/processors/abstract-processor.d.ts +3 -3
- package/distribution/processors/abstract-processor.d.ts.map +1 -1
- package/distribution/processors/abstract-processor.js +6 -6
- package/distribution/processors/abstract-processor.js.map +1 -1
- package/distribution/processors/commit-processor.d.ts.map +1 -1
- package/distribution/processors/commit-processor.js +10 -10
- package/distribution/processors/commit-processor.js.map +1 -1
- package/distribution/processors/precommit-processor.js +2 -2
- package/distribution/processors/precommit-processor.js.map +1 -1
- package/distribution/processors/prevote-processor.js +2 -2
- package/distribution/processors/prevote-processor.js.map +1 -1
- package/distribution/processors/proposal-processor.d.ts +1 -1
- package/distribution/processors/proposal-processor.d.ts.map +1 -1
- package/distribution/processors/proposal-processor.js +12 -12
- package/distribution/processors/proposal-processor.js.map +1 -1
- package/distribution/round-state-repository.d.ts +1 -1
- package/distribution/round-state-repository.d.ts.map +1 -1
- package/distribution/round-state-repository.js +5 -5
- package/distribution/round-state-repository.js.map +1 -1
- package/distribution/round-state.d.ts +3 -3
- package/distribution/round-state.d.ts.map +1 -1
- package/distribution/round-state.js +39 -38
- package/distribution/round-state.js.map +1 -1
- package/package.json +10 -8
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
2
1
|
import { Contracts } from "@mainsail/contracts";
|
|
3
2
|
export declare class Aggregator implements Contracts.Consensus.Aggregator {
|
|
4
3
|
private readonly validatorSet;
|
|
5
4
|
private readonly workerPool;
|
|
6
5
|
aggregate(majority: Map<number, {
|
|
7
6
|
signature: string;
|
|
8
|
-
}>,
|
|
9
|
-
verify(signature: Contracts.Crypto.AggregatedSignature, data: Buffer,
|
|
7
|
+
}>, roundValidators: number): Promise<Contracts.Crypto.AggregatedSignature>;
|
|
8
|
+
verify(signature: Contracts.Crypto.AggregatedSignature, data: Buffer, roundValidators: number): Promise<boolean>;
|
|
10
9
|
}
|
|
11
10
|
//# sourceMappingURL=aggregator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aggregator.d.ts","sourceRoot":"","sources":["../source/aggregator.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"aggregator.d.ts","sourceRoot":"","sources":["../source/aggregator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAe,MAAM,qBAAqB,CAAC;AAE7D,qBACa,UAAW,YAAW,SAAS,CAAC,SAAS,CAAC,UAAU;IAEhE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAkC;IAG/D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA+B;IAE7C,SAAS,CACrB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,EAC5C,eAAe,EAAE,MAAM,GACrB,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,mBAAmB,CAAC;IAuB1C,MAAM,CACX,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,mBAAmB,EAC/C,IAAI,EAAE,MAAM,EACZ,eAAe,EAAE,MAAM,GACrB,OAAO,CAAC,OAAO,CAAC;CAoBnB"}
|
|
@@ -7,16 +7,16 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
8
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
9
|
};
|
|
10
|
+
import { isMajority } from "@mainsail/blockchain-utils";
|
|
10
11
|
import { inject, injectable } from "@mainsail/container";
|
|
11
12
|
import { Contracts, Identifiers } from "@mainsail/contracts";
|
|
12
|
-
import { Utils } from "@mainsail/kernel";
|
|
13
13
|
let Aggregator = class Aggregator {
|
|
14
|
-
async aggregate(majority,
|
|
15
|
-
if (!
|
|
14
|
+
async aggregate(majority, roundValidators) {
|
|
15
|
+
if (!isMajority(majority.size, roundValidators)) {
|
|
16
16
|
throw new Error("Failed to aggregate signatures, because the majority is not reached.");
|
|
17
17
|
}
|
|
18
18
|
const signatures = [];
|
|
19
|
-
const validators = Array.from({ length:
|
|
19
|
+
const validators = Array.from({ length: roundValidators }).fill(false);
|
|
20
20
|
for (const [key, { signature }] of majority) {
|
|
21
21
|
signatures.push(Buffer.from(signature, "hex"));
|
|
22
22
|
validators[key] = true;
|
|
@@ -28,11 +28,11 @@ let Aggregator = class Aggregator {
|
|
|
28
28
|
validators,
|
|
29
29
|
};
|
|
30
30
|
}
|
|
31
|
-
async verify(signature, data,
|
|
31
|
+
async verify(signature, data, roundValidators) {
|
|
32
32
|
const validatorPublicKeys = signature.validators
|
|
33
33
|
.map((v, index) => (v ? Buffer.from(this.validatorSet.getValidator(index).blsPublicKey, "hex") : undefined))
|
|
34
34
|
.filter((item) => !!item);
|
|
35
|
-
if (!
|
|
35
|
+
if (!isMajority(validatorPublicKeys.length, roundValidators)) {
|
|
36
36
|
return false;
|
|
37
37
|
}
|
|
38
38
|
const worker = await this.workerPool.getWorker();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aggregator.js","sourceRoot":"","sources":["../source/aggregator.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"aggregator.js","sourceRoot":"","sources":["../source/aggregator.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGtD,IAAM,UAAU,GAAhB,MAAM,UAAU;IAOf,KAAK,CAAC,SAAS,CACrB,QAA4C,EAC5C,eAAuB;QAEvB,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC,EAAE,CAAC;YACjD,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAC;QACzF,CAAC;QAED,MAAM,UAAU,GAAa,EAAE,CAAC;QAEhC,MAAM,UAAU,GAAc,KAAK,CAAC,IAAI,CAAU,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAE3F,KAAK,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,CAAC,IAAI,QAAQ,EAAE,CAAC;YAC7C,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;YAC/C,UAAU,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;QACxB,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC;QACjD,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QAE3E,OAAO;YACN,SAAS;YACT,UAAU;SACV,CAAC;IACH,CAAC;IAED,KAAK,CAAC,MAAM,CACX,SAA+C,EAC/C,IAAY,EACZ,eAAuB;QAEvB,MAAM,mBAAmB,GAAa,SAAS,CAAC,UAAU;aACxD,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;aAC3G,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAE3C,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC,MAAM,EAAE,eAAe,CAAC,EAAE,CAAC;YAC9D,OAAO,KAAK,CAAC;QACd,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC;QAEjD,MAAM,mBAAmB,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,WAAW,EAAE,mBAAmB,CAAC,CAAC;QAE5F,OAAO,MAAM,MAAM,CAAC,kBAAkB,CACrC,QAAQ,EACR,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,KAAK,CAAC,EACvC,IAAI,EACJ,MAAM,CAAC,IAAI,CAAC,mBAAmB,EAAE,KAAK,CAAC,CACvC,CAAC;IACH,CAAC;CACD,CAAA;AAvDiB;IADhB,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,OAAO,CAAC;;gDACsB;AAG9C;IADhB,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,UAAU,CAAC;;8CACc;AAL9C,UAAU;IADtB,UAAU,EAAE;GACA,UAAU,CAyDtB"}
|
|
@@ -14,19 +14,19 @@ let Bootstrapper = class Bootstrapper {
|
|
|
14
14
|
const proposals = await this.storage.getProposals();
|
|
15
15
|
this.logger.info(`Consensus Bootstrap - Proposals: ${proposals.length}`);
|
|
16
16
|
for (const proposal of proposals) {
|
|
17
|
-
const roundState = this.roundStateRepo.getRoundState(proposal.
|
|
17
|
+
const roundState = this.roundStateRepo.getRoundState(proposal.blockNumber, proposal.round);
|
|
18
18
|
roundState.addProposal(proposal);
|
|
19
19
|
}
|
|
20
20
|
const prevotes = await this.storage.getPrevotes();
|
|
21
21
|
this.logger.info(`Consensus Bootstrap - Prevotes: ${prevotes.length}`);
|
|
22
22
|
for (const prevote of prevotes) {
|
|
23
|
-
const roundState = this.roundStateRepo.getRoundState(prevote.
|
|
23
|
+
const roundState = this.roundStateRepo.getRoundState(prevote.blockNumber, prevote.round);
|
|
24
24
|
roundState.addPrevote(prevote);
|
|
25
25
|
}
|
|
26
26
|
const precommits = await this.storage.getPrecommits();
|
|
27
27
|
this.logger.info(`Consensus Bootstrap - Precommits: ${precommits.length}`);
|
|
28
28
|
for (const precommit of precommits) {
|
|
29
|
-
const roundState = this.roundStateRepo.getRoundState(precommit.
|
|
29
|
+
const roundState = this.roundStateRepo.getRoundState(precommit.blockNumber, precommit.round);
|
|
30
30
|
roundState.addPrecommit(precommit);
|
|
31
31
|
}
|
|
32
32
|
const state = (await this.storage.getState());
|
|
@@ -35,12 +35,12 @@ let Bootstrapper = class Bootstrapper {
|
|
|
35
35
|
}
|
|
36
36
|
if (state.validRound !== undefined) {
|
|
37
37
|
// TODO: ensure validRound points to an existing round?
|
|
38
|
-
const roundState = this.roundStateRepo.getRoundState(state.
|
|
38
|
+
const roundState = this.roundStateRepo.getRoundState(state.blockNumber, state.validRound);
|
|
39
39
|
state.validValue = roundState;
|
|
40
40
|
}
|
|
41
41
|
if (state.lockedRound !== undefined) {
|
|
42
42
|
// TODO: ensure lockedRound points to an existing round?
|
|
43
|
-
const roundState = this.roundStateRepo.getRoundState(state.
|
|
43
|
+
const roundState = this.roundStateRepo.getRoundState(state.blockNumber, state.lockedRound);
|
|
44
44
|
state.lockedValue = roundState;
|
|
45
45
|
}
|
|
46
46
|
return state;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrapper.js","sourceRoot":"","sources":["../source/bootstrapper.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,WAAW,EAAS,MAAM,qBAAqB,CAAC;AAG7D,IAAM,YAAY,GAAlB,MAAM,YAAY;IAUjB,KAAK,CAAC,GAAG;QACf,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;QAEpD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oCAAoC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;QAEzE,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YAClC,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"bootstrapper.js","sourceRoot":"","sources":["../source/bootstrapper.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,WAAW,EAAS,MAAM,qBAAqB,CAAC;AAG7D,IAAM,YAAY,GAAlB,MAAM,YAAY;IAUjB,KAAK,CAAC,GAAG;QACf,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;QAEpD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oCAAoC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;QAEzE,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YAClC,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;YAC3F,UAAU,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QAClC,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QAElD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,mCAAmC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QACvE,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAChC,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;YACzF,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAChC,CAAC;QAED,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;QAEtD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,qCAAqC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;QAC3E,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACpC,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,SAAS,CAAC,WAAW,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC;YAC7F,UAAU,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;QACpC,CAAC;QAED,MAAM,KAAK,GAAG,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAyD,CAAC;QACtG,IAAI,CAAC,KAAK,EAAE,CAAC;YACZ,OAAO,SAAS,CAAC;QAClB,CAAC;QAED,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YACpC,uDAAuD;YACvD,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;YAC1F,KAAK,CAAC,UAAU,GAAG,UAAU,CAAC;QAC/B,CAAC;QAED,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;YACrC,wDAAwD;YACxD,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;YAC3F,KAAK,CAAC,WAAW,GAAG,UAAU,CAAC;QAChC,CAAC;QAED,OAAO,KAAK,CAAC;IACd,CAAC;CACD,CAAA;AArDiB;IADhB,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC;;4CACS;AAGjC;IADhB,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,oBAAoB,CAAC;;oDACwB;AAG1D;IADhB,MAAM,CAAC,WAAW,CAAC,gBAAgB,CAAC,OAAO,CAAC;;6CACiB;AARlD,YAAY;IADxB,UAAU,EAAE;GACA,YAAY,CAuDxB"}
|
|
@@ -2,9 +2,8 @@ import { Contracts } from "@mainsail/contracts";
|
|
|
2
2
|
export declare class CommitState implements Contracts.Processor.ProcessableUnit {
|
|
3
3
|
#private;
|
|
4
4
|
private readonly validatorSet;
|
|
5
|
-
get
|
|
5
|
+
get blockNumber(): number;
|
|
6
6
|
get round(): number;
|
|
7
|
-
get persist(): boolean;
|
|
8
7
|
get validators(): string[];
|
|
9
8
|
configure(commit: Contracts.Crypto.Commit): CommitState;
|
|
10
9
|
getBlock(): Contracts.Crypto.Block;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commit-state.d.ts","sourceRoot":"","sources":["../source/commit-state.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAe,MAAM,qBAAqB,CAAC;AAE7D,qBACa,WAAY,YAAW,SAAS,CAAC,SAAS,CAAC,eAAe;;IAEtE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAkC;IAO/D,IAAW,
|
|
1
|
+
{"version":3,"file":"commit-state.d.ts","sourceRoot":"","sources":["../source/commit-state.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAe,MAAM,qBAAqB,CAAC;AAE7D,qBACa,WAAY,YAAW,SAAS,CAAC,SAAS,CAAC,eAAe;;IAEtE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAkC;IAO/D,IAAW,WAAW,IAAI,MAAM,CAE/B;IAED,IAAW,KAAK,IAAI,MAAM,CAEzB;IAED,IAAW,UAAU,IAAI,MAAM,EAAE,CAEhC;IAEM,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,GAAG,WAAW;IAYvD,QAAQ,IAAI,SAAS,CAAC,MAAM,CAAC,KAAK;IAIlC,kBAAkB,CAAC,eAAe,EAAE,SAAS,CAAC,SAAS,CAAC,oBAAoB,GAAG,IAAI;IAInF,kBAAkB,IAAI,OAAO;IAI7B,kBAAkB,IAAI,SAAS,CAAC,SAAS,CAAC,oBAAoB;IAQ9D,iBAAiB,IAAI,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,aAAa,CAAC;IAIvD,iBAAiB,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,IAAI;IAI/D,SAAS,IAAI,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC;CAG1D"}
|
|
@@ -28,21 +28,18 @@ let CommitState = class CommitState {
|
|
|
28
28
|
_CommitState_validators.set(this, new Map());
|
|
29
29
|
_CommitState_accountUpdates.set(this, []);
|
|
30
30
|
}
|
|
31
|
-
get
|
|
32
|
-
return __classPrivateFieldGet(this, _CommitState_commit, "f").block.data.
|
|
31
|
+
get blockNumber() {
|
|
32
|
+
return __classPrivateFieldGet(this, _CommitState_commit, "f").block.data.number;
|
|
33
33
|
}
|
|
34
34
|
get round() {
|
|
35
35
|
return __classPrivateFieldGet(this, _CommitState_commit, "f").proof.round;
|
|
36
36
|
}
|
|
37
|
-
get persist() {
|
|
38
|
-
return false; // Block downloader will store block in database, to improve performance
|
|
39
|
-
}
|
|
40
37
|
get validators() {
|
|
41
38
|
return [...__classPrivateFieldGet(this, _CommitState_validators, "f").keys()];
|
|
42
39
|
}
|
|
43
40
|
configure(commit) {
|
|
44
41
|
__classPrivateFieldSet(this, _CommitState_commit, commit, "f");
|
|
45
|
-
const validators = this.validatorSet.
|
|
42
|
+
const validators = this.validatorSet.getRoundValidators();
|
|
46
43
|
for (const validator of validators) {
|
|
47
44
|
const consensusPublicKey = validator.blsPublicKey;
|
|
48
45
|
__classPrivateFieldGet(this, _CommitState_validators, "f").set(consensusPublicKey, validator);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commit-state.js","sourceRoot":"","sources":["../source/commit-state.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGtD,IAAM,WAAW,GAAjB,MAAM,WAAW;IAAjB;QAIN,sCAAkC;QAClC,+CAA4D;QAC5D,kCAAc,IAAI,GAAG,EAA2C,EAAC;QACjE,sCAAsD,EAAE,EAAC;
|
|
1
|
+
{"version":3,"file":"commit-state.js","sourceRoot":"","sources":["../source/commit-state.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGtD,IAAM,WAAW,GAAjB,MAAM,WAAW;IAAjB;QAIN,sCAAkC;QAClC,+CAA4D;QAC5D,kCAAc,IAAI,GAAG,EAA2C,EAAC;QACjE,sCAAsD,EAAE,EAAC;IAyD1D,CAAC;IAvDA,IAAW,WAAW;QACrB,OAAO,uBAAA,IAAI,2BAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;IACvC,CAAC;IAED,IAAW,KAAK;QACf,OAAO,uBAAA,IAAI,2BAAQ,CAAC,KAAK,CAAC,KAAK,CAAC;IACjC,CAAC;IAED,IAAW,UAAU;QACpB,OAAO,CAAC,GAAG,uBAAA,IAAI,+BAAY,CAAC,IAAI,EAAE,CAAC,CAAC;IACrC,CAAC;IAEM,SAAS,CAAC,MAA+B;QAC/C,uBAAA,IAAI,uBAAW,MAAM,MAAA,CAAC;QAEtB,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,kBAAkB,EAAE,CAAC;QAC1D,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACpC,MAAM,kBAAkB,GAAG,SAAS,CAAC,YAAY,CAAC;YAClD,uBAAA,IAAI,+BAAY,CAAC,GAAG,CAAC,kBAAkB,EAAE,SAAS,CAAC,CAAC;QACrD,CAAC;QAED,OAAO,IAAI,CAAC;IACb,CAAC;IAEM,QAAQ;QACd,OAAO,uBAAA,IAAI,2BAAQ,CAAC,KAAK,CAAC;IAC3B,CAAC;IAEM,kBAAkB,CAAC,eAAyD;QAClF,uBAAA,IAAI,gCAAoB,eAAe,MAAA,CAAC;IACzC,CAAC;IAEM,kBAAkB;QACxB,OAAO,uBAAA,IAAI,oCAAiB,KAAK,SAAS,CAAC;IAC5C,CAAC;IAEM,kBAAkB;QACxB,IAAI,uBAAA,IAAI,oCAAiB,IAAI,SAAS,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACnD,CAAC;QAED,OAAO,uBAAA,IAAI,oCAAiB,CAAC;IAC9B,CAAC;IAEM,iBAAiB;QACvB,OAAO,uBAAA,IAAI,mCAAgB,CAAC;IAC7B,CAAC;IAEM,iBAAiB,CAAC,QAA4C;QACpE,uBAAA,IAAI,+BAAmB,QAAQ,MAAA,CAAC;IACjC,CAAC;IAEM,KAAK,CAAC,SAAS;QACrB,OAAO,uBAAA,IAAI,2BAAQ,CAAC;IACrB,CAAC;CACD,CAAA;;;;;AA9DiB;IADhB,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,OAAO,CAAC;;iDACsB;AAFnD,WAAW;IADvB,UAAU,EAAE;GACA,WAAW,CAgEvB"}
|
|
@@ -16,7 +16,7 @@ export declare class Consensus implements Contracts.Consensus.Service {
|
|
|
16
16
|
private readonly validatorSet;
|
|
17
17
|
private readonly eventDispatcher;
|
|
18
18
|
private readonly logger;
|
|
19
|
-
|
|
19
|
+
getBlockNumber(): number;
|
|
20
20
|
getRound(): number;
|
|
21
21
|
setRound(round: number): void;
|
|
22
22
|
getStep(): Contracts.Consensus.Step;
|
|
@@ -40,9 +40,9 @@ export declare class Consensus implements Contracts.Consensus.Service {
|
|
|
40
40
|
protected onMajorityPrecommitAny(roundState: Contracts.Consensus.RoundState): Promise<void>;
|
|
41
41
|
protected onMajorityPrecommit(roundState: Contracts.Processor.ProcessableUnit): Promise<void>;
|
|
42
42
|
protected onMinorityWithHigherRound(roundState: Contracts.Processor.ProcessableUnit): Promise<void>;
|
|
43
|
-
onTimeoutPropose(
|
|
44
|
-
onTimeoutPrevote(
|
|
45
|
-
onTimeoutPrecommit(
|
|
43
|
+
onTimeoutPropose(blockNumber: number, round: number): Promise<void>;
|
|
44
|
+
onTimeoutPrevote(blockNumber: number, round: number): Promise<void>;
|
|
45
|
+
onTimeoutPrecommit(blockNumber: number, round: number): Promise<void>;
|
|
46
46
|
propose(roundState: Contracts.Consensus.RoundState): Promise<void>;
|
|
47
47
|
prevote(value?: string): Promise<void>;
|
|
48
48
|
precommit(value?: string): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consensus.d.ts","sourceRoot":"","sources":["../source/consensus.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAuB,MAAM,qBAAqB,CAAC;AAIrE,qBACa,SAAU,YAAW,SAAS,CAAC,SAAS,CAAC,OAAO;;IAE5D,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAgC;IAGpD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAoC;IAGjE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAkC;IAGhE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsC;IAGhE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAyB;IAGpD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAyC;IAG3E,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAwC;IAGzE,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA0C;IAG7E,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiC;IAG3D,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAA2C;IAGhF,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAA4C;IAGjF,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAyB;IAGpD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAkC;IAG/D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAoC;IAGpE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA2B;IAmB3C,
|
|
1
|
+
{"version":3,"file":"consensus.d.ts","sourceRoot":"","sources":["../source/consensus.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,15 +18,15 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
|
|
|
18
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
19
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
20
20
|
};
|
|
21
|
-
var _Consensus_instances,
|
|
21
|
+
var _Consensus_instances, _Consensus_blockNumber, _Consensus_round, _Consensus_step, _Consensus_lockedValue, _Consensus_validValue, _Consensus_didMajorityPrevote, _Consensus_didMajorityPrecommit, _Consensus_isDisposed, _Consensus_pendingJobs, _Consensus_proposalPromise, _Consensus_roundStartTime, _Consensus_handlerLock, _Consensus_isInvalidRoundState, _Consensus_makeProposal, _Consensus_bootstrap, _Consensus_processProposal, _Consensus_processBlock;
|
|
22
22
|
import { inject, injectable } from "@mainsail/container";
|
|
23
23
|
import { Contracts, Events, Identifiers } from "@mainsail/contracts";
|
|
24
|
-
import {
|
|
24
|
+
import { Lock } from "@mainsail/utils";
|
|
25
25
|
import dayjs from "dayjs";
|
|
26
26
|
let Consensus = class Consensus {
|
|
27
27
|
constructor() {
|
|
28
28
|
_Consensus_instances.add(this);
|
|
29
|
-
|
|
29
|
+
_Consensus_blockNumber.set(this, 1);
|
|
30
30
|
_Consensus_round.set(this, 0);
|
|
31
31
|
_Consensus_step.set(this, Contracts.Consensus.Step.Propose);
|
|
32
32
|
_Consensus_lockedValue.set(this, void 0);
|
|
@@ -38,10 +38,10 @@ let Consensus = class Consensus {
|
|
|
38
38
|
_Consensus_proposalPromise.set(this, void 0);
|
|
39
39
|
_Consensus_roundStartTime.set(this, 0);
|
|
40
40
|
// Handler lock is different than commit lock. It is used to prevent parallel processing and it is similar to queue.
|
|
41
|
-
_Consensus_handlerLock.set(this, new
|
|
41
|
+
_Consensus_handlerLock.set(this, new Lock());
|
|
42
42
|
}
|
|
43
|
-
|
|
44
|
-
return __classPrivateFieldGet(this,
|
|
43
|
+
getBlockNumber() {
|
|
44
|
+
return __classPrivateFieldGet(this, _Consensus_blockNumber, "f");
|
|
45
45
|
}
|
|
46
46
|
getRound() {
|
|
47
47
|
return __classPrivateFieldGet(this, _Consensus_round, "f");
|
|
@@ -73,7 +73,7 @@ let Consensus = class Consensus {
|
|
|
73
73
|
}
|
|
74
74
|
getState() {
|
|
75
75
|
return {
|
|
76
|
-
|
|
76
|
+
blockNumber: __classPrivateFieldGet(this, _Consensus_blockNumber, "f"),
|
|
77
77
|
lockedRound: this.getLockedRound(),
|
|
78
78
|
round: __classPrivateFieldGet(this, _Consensus_round, "f"),
|
|
79
79
|
step: __classPrivateFieldGet(this, _Consensus_step, "f"),
|
|
@@ -83,10 +83,10 @@ let Consensus = class Consensus {
|
|
|
83
83
|
async run() {
|
|
84
84
|
await __classPrivateFieldGet(this, _Consensus_instances, "m", _Consensus_bootstrap).call(this);
|
|
85
85
|
await this.startRound(__classPrivateFieldGet(this, _Consensus_round, "f"));
|
|
86
|
-
await this.handle(this.roundStateRepository.getRoundState(__classPrivateFieldGet(this,
|
|
86
|
+
await this.handle(this.roundStateRepository.getRoundState(__classPrivateFieldGet(this, _Consensus_blockNumber, "f"), __classPrivateFieldGet(this, _Consensus_round, "f")));
|
|
87
87
|
// Rerun previous rounds, in case proposal & +2/3 precommits were received
|
|
88
88
|
for (let index = 0; index < __classPrivateFieldGet(this, _Consensus_round, "f"); index++) {
|
|
89
|
-
await this.handle(this.roundStateRepository.getRoundState(__classPrivateFieldGet(this,
|
|
89
|
+
await this.handle(this.roundStateRepository.getRoundState(__classPrivateFieldGet(this, _Consensus_blockNumber, "f"), index));
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
async dispose() {
|
|
@@ -146,15 +146,15 @@ let Consensus = class Consensus {
|
|
|
146
146
|
if (__classPrivateFieldGet(this, _Consensus_isDisposed, "f")) {
|
|
147
147
|
return;
|
|
148
148
|
}
|
|
149
|
-
const roundState = this.roundStateRepository.getRoundState(__classPrivateFieldGet(this,
|
|
150
|
-
this.logger.info(`>> Starting new round: ${__classPrivateFieldGet(this,
|
|
149
|
+
const roundState = this.roundStateRepository.getRoundState(__classPrivateFieldGet(this, _Consensus_blockNumber, "f"), __classPrivateFieldGet(this, _Consensus_round, "f"));
|
|
150
|
+
this.logger.info(`>> Starting new round: ${__classPrivateFieldGet(this, _Consensus_blockNumber, "f")}/${__classPrivateFieldGet(this, _Consensus_round, "f")} with proposer: ${roundState.proposer.address}`);
|
|
151
151
|
await this.eventDispatcher.dispatch(Events.ConsensusEvent.RoundStarted, this.getState());
|
|
152
152
|
this.scheduler.scheduleTimeoutBlockPrepare(this.scheduler.getNextBlockTimestamp(__classPrivateFieldGet(this, _Consensus_roundStartTime, "f")));
|
|
153
153
|
// TODO: Skip on sync
|
|
154
154
|
await this.propose(roundState);
|
|
155
155
|
}
|
|
156
156
|
async onTimeoutStartRound() {
|
|
157
|
-
this.scheduler.scheduleTimeoutPropose(__classPrivateFieldGet(this,
|
|
157
|
+
this.scheduler.scheduleTimeoutPropose(__classPrivateFieldGet(this, _Consensus_blockNumber, "f"), __classPrivateFieldGet(this, _Consensus_round, "f"));
|
|
158
158
|
if (__classPrivateFieldGet(this, _Consensus_proposalPromise, "f")) {
|
|
159
159
|
const proposal = await __classPrivateFieldGet(this, _Consensus_proposalPromise, "f");
|
|
160
160
|
__classPrivateFieldSet(this, _Consensus_proposalPromise, undefined, "f");
|
|
@@ -171,9 +171,9 @@ let Consensus = class Consensus {
|
|
|
171
171
|
}
|
|
172
172
|
__classPrivateFieldSet(this, _Consensus_step, Contracts.Consensus.Step.Prevote, "f");
|
|
173
173
|
const { block } = proposal.getData();
|
|
174
|
-
this.logger.info(`Received proposal ${__classPrivateFieldGet(this,
|
|
174
|
+
this.logger.info(`Received proposal ${__classPrivateFieldGet(this, _Consensus_blockNumber, "f")}/${__classPrivateFieldGet(this, _Consensus_round, "f")} block hash: ${block.data.hash}`);
|
|
175
175
|
await this.eventDispatcher.dispatch(Events.ConsensusEvent.ProposalAccepted, this.getState());
|
|
176
|
-
await this.prevote(roundState.getProcessorResult() ? block.data.
|
|
176
|
+
await this.prevote(roundState.getProcessorResult() ? block.data.hash : undefined);
|
|
177
177
|
}
|
|
178
178
|
async onProposalLocked(roundState) {
|
|
179
179
|
const proposal = roundState.getProposal();
|
|
@@ -187,11 +187,11 @@ let Consensus = class Consensus {
|
|
|
187
187
|
}
|
|
188
188
|
const { block } = proposal.getData();
|
|
189
189
|
__classPrivateFieldSet(this, _Consensus_step, Contracts.Consensus.Step.Prevote, "f");
|
|
190
|
-
this.logger.info(`Received proposal ${__classPrivateFieldGet(this,
|
|
190
|
+
this.logger.info(`Received proposal ${__classPrivateFieldGet(this, _Consensus_blockNumber, "f")}/${__classPrivateFieldGet(this, _Consensus_round, "f")} with locked block hash: ${block.data.hash}`);
|
|
191
191
|
await this.eventDispatcher.dispatch(Events.ConsensusEvent.ProposalAccepted, this.getState());
|
|
192
192
|
const lockedRound = this.getLockedRound();
|
|
193
193
|
if ((!lockedRound || lockedRound <= proposal.validRound) && roundState.getProcessorResult()) {
|
|
194
|
-
await this.prevote(block.data.
|
|
194
|
+
await this.prevote(block.data.hash);
|
|
195
195
|
}
|
|
196
196
|
else {
|
|
197
197
|
await this.prevote();
|
|
@@ -207,14 +207,14 @@ let Consensus = class Consensus {
|
|
|
207
207
|
return;
|
|
208
208
|
}
|
|
209
209
|
const { block } = proposal.getData();
|
|
210
|
-
this.logger.info(`Received +2/3 prevotes for ${__classPrivateFieldGet(this,
|
|
210
|
+
this.logger.info(`Received +2/3 prevotes for ${__classPrivateFieldGet(this, _Consensus_blockNumber, "f")}/${__classPrivateFieldGet(this, _Consensus_round, "f")} block hash: ${block.data.hash}`);
|
|
211
211
|
__classPrivateFieldSet(this, _Consensus_didMajorityPrevote, true, "f");
|
|
212
212
|
if (__classPrivateFieldGet(this, _Consensus_step, "f") === Contracts.Consensus.Step.Prevote) {
|
|
213
213
|
__classPrivateFieldSet(this, _Consensus_lockedValue, roundState, "f");
|
|
214
214
|
__classPrivateFieldSet(this, _Consensus_validValue, roundState, "f");
|
|
215
215
|
__classPrivateFieldSet(this, _Consensus_step, Contracts.Consensus.Step.Precommit, "f");
|
|
216
216
|
await this.eventDispatcher.dispatch(Events.ConsensusEvent.PrevotedProposal, this.getState());
|
|
217
|
-
await this.precommit(block.data.
|
|
217
|
+
await this.precommit(block.data.hash);
|
|
218
218
|
}
|
|
219
219
|
else {
|
|
220
220
|
__classPrivateFieldSet(this, _Consensus_validValue, roundState, "f");
|
|
@@ -225,7 +225,7 @@ let Consensus = class Consensus {
|
|
|
225
225
|
if (__classPrivateFieldGet(this, _Consensus_step, "f") !== Contracts.Consensus.Step.Prevote || __classPrivateFieldGet(this, _Consensus_instances, "m", _Consensus_isInvalidRoundState).call(this, roundState)) {
|
|
226
226
|
return;
|
|
227
227
|
}
|
|
228
|
-
if (this.scheduler.scheduleTimeoutPrevote(__classPrivateFieldGet(this,
|
|
228
|
+
if (this.scheduler.scheduleTimeoutPrevote(__classPrivateFieldGet(this, _Consensus_blockNumber, "f"), __classPrivateFieldGet(this, _Consensus_round, "f"))) {
|
|
229
229
|
await this.eventDispatcher.dispatch(Events.ConsensusEvent.PrevotedAny, this.getState());
|
|
230
230
|
}
|
|
231
231
|
}
|
|
@@ -233,7 +233,7 @@ let Consensus = class Consensus {
|
|
|
233
233
|
if (__classPrivateFieldGet(this, _Consensus_step, "f") !== Contracts.Consensus.Step.Prevote || __classPrivateFieldGet(this, _Consensus_instances, "m", _Consensus_isInvalidRoundState).call(this, roundState)) {
|
|
234
234
|
return;
|
|
235
235
|
}
|
|
236
|
-
this.logger.info(`Received +2/3 prevotes for ${__classPrivateFieldGet(this,
|
|
236
|
+
this.logger.info(`Received +2/3 prevotes for ${__classPrivateFieldGet(this, _Consensus_blockNumber, "f")}/${__classPrivateFieldGet(this, _Consensus_round, "f")} blockHash: null`);
|
|
237
237
|
__classPrivateFieldSet(this, _Consensus_step, Contracts.Consensus.Step.Precommit, "f");
|
|
238
238
|
await this.eventDispatcher.dispatch(Events.ConsensusEvent.PrevotedNull, this.getState());
|
|
239
239
|
await this.precommit();
|
|
@@ -242,22 +242,22 @@ let Consensus = class Consensus {
|
|
|
242
242
|
if (__classPrivateFieldGet(this, _Consensus_instances, "m", _Consensus_isInvalidRoundState).call(this, roundState)) {
|
|
243
243
|
return;
|
|
244
244
|
}
|
|
245
|
-
if (this.scheduler.scheduleTimeoutPrecommit(__classPrivateFieldGet(this,
|
|
245
|
+
if (this.scheduler.scheduleTimeoutPrecommit(__classPrivateFieldGet(this, _Consensus_blockNumber, "f"), __classPrivateFieldGet(this, _Consensus_round, "f"))) {
|
|
246
246
|
await this.eventDispatcher.dispatch(Events.ConsensusEvent.PrecommitedAny, this.getState());
|
|
247
247
|
}
|
|
248
248
|
}
|
|
249
249
|
async onMajorityPrecommit(roundState) {
|
|
250
|
-
// TODO: Only
|
|
251
|
-
if (__classPrivateFieldGet(this, _Consensus_didMajorityPrecommit, "f") || roundState.
|
|
250
|
+
// TODO: Only block number must match. Round can be any. Add tests
|
|
251
|
+
if (__classPrivateFieldGet(this, _Consensus_didMajorityPrecommit, "f") || roundState.blockNumber !== __classPrivateFieldGet(this, _Consensus_blockNumber, "f")) {
|
|
252
252
|
return;
|
|
253
253
|
}
|
|
254
254
|
__classPrivateFieldSet(this, _Consensus_didMajorityPrecommit, true, "f");
|
|
255
255
|
const block = roundState.getBlock();
|
|
256
256
|
if (!roundState.getProcessorResult().success) {
|
|
257
|
-
this.logger.info(`Block ${block.data.
|
|
257
|
+
this.logger.info(`Block ${block.data.hash} on block number ${__classPrivateFieldGet(this, _Consensus_blockNumber, "f")} received +2/3 precommits but is invalid`);
|
|
258
258
|
return;
|
|
259
259
|
}
|
|
260
|
-
this.logger.info(`Received +2/3 precommits for ${__classPrivateFieldGet(this,
|
|
260
|
+
this.logger.info(`Received +2/3 precommits for ${__classPrivateFieldGet(this, _Consensus_blockNumber, "f")}/${roundState.round} block hash: ${block.data.hash}`);
|
|
261
261
|
await this.eventDispatcher.dispatch(Events.ConsensusEvent.PrecommitedProposal, this.getState());
|
|
262
262
|
await this.commitLock.runExclusive(async () => {
|
|
263
263
|
var _a;
|
|
@@ -268,47 +268,51 @@ let Consensus = class Consensus {
|
|
|
268
268
|
await this.app.terminate("Failed to commit block", error);
|
|
269
269
|
}
|
|
270
270
|
this.roundStateRepository.clear();
|
|
271
|
-
__classPrivateFieldSet(this,
|
|
271
|
+
__classPrivateFieldSet(this, _Consensus_blockNumber, (_a = __classPrivateFieldGet(this, _Consensus_blockNumber, "f"), _a++, _a), "f");
|
|
272
272
|
__classPrivateFieldSet(this, _Consensus_lockedValue, undefined, "f");
|
|
273
273
|
__classPrivateFieldSet(this, _Consensus_validValue, undefined, "f");
|
|
274
274
|
await this.startRound(0);
|
|
275
275
|
});
|
|
276
276
|
}
|
|
277
277
|
async onMinorityWithHigherRound(roundState) {
|
|
278
|
-
if (roundState.
|
|
278
|
+
if (roundState.blockNumber !== __classPrivateFieldGet(this, _Consensus_blockNumber, "f") || roundState.round <= __classPrivateFieldGet(this, _Consensus_round, "f")) {
|
|
279
279
|
return;
|
|
280
280
|
}
|
|
281
281
|
await this.startRound(roundState.round);
|
|
282
282
|
}
|
|
283
|
-
async onTimeoutPropose(
|
|
283
|
+
async onTimeoutPropose(blockNumber, round) {
|
|
284
284
|
await __classPrivateFieldGet(this, _Consensus_handlerLock, "f").runExclusive(async () => {
|
|
285
|
-
if (__classPrivateFieldGet(this, _Consensus_step, "f") !== Contracts.Consensus.Step.Propose ||
|
|
285
|
+
if (__classPrivateFieldGet(this, _Consensus_step, "f") !== Contracts.Consensus.Step.Propose ||
|
|
286
|
+
__classPrivateFieldGet(this, _Consensus_blockNumber, "f") !== blockNumber ||
|
|
287
|
+
__classPrivateFieldGet(this, _Consensus_round, "f") !== round) {
|
|
286
288
|
return;
|
|
287
289
|
}
|
|
288
|
-
this.logger.info(`Timeout to propose ${__classPrivateFieldGet(this,
|
|
290
|
+
this.logger.info(`Timeout to propose ${__classPrivateFieldGet(this, _Consensus_blockNumber, "f")}/${__classPrivateFieldGet(this, _Consensus_round, "f")} expired`);
|
|
289
291
|
__classPrivateFieldSet(this, _Consensus_step, Contracts.Consensus.Step.Prevote, "f");
|
|
290
292
|
await this.prevote();
|
|
291
293
|
});
|
|
292
294
|
}
|
|
293
|
-
async onTimeoutPrevote(
|
|
295
|
+
async onTimeoutPrevote(blockNumber, round) {
|
|
294
296
|
await __classPrivateFieldGet(this, _Consensus_handlerLock, "f").runExclusive(async () => {
|
|
295
|
-
if (__classPrivateFieldGet(this, _Consensus_step, "f") !== Contracts.Consensus.Step.Prevote ||
|
|
297
|
+
if (__classPrivateFieldGet(this, _Consensus_step, "f") !== Contracts.Consensus.Step.Prevote ||
|
|
298
|
+
__classPrivateFieldGet(this, _Consensus_blockNumber, "f") !== blockNumber ||
|
|
299
|
+
__classPrivateFieldGet(this, _Consensus_round, "f") !== round) {
|
|
296
300
|
return;
|
|
297
301
|
}
|
|
298
|
-
this.logger.info(`Timeout to prevote ${__classPrivateFieldGet(this,
|
|
299
|
-
this.roundStateRepository.getRoundState(__classPrivateFieldGet(this,
|
|
302
|
+
this.logger.info(`Timeout to prevote ${__classPrivateFieldGet(this, _Consensus_blockNumber, "f")}/${__classPrivateFieldGet(this, _Consensus_round, "f")} expired`);
|
|
303
|
+
this.roundStateRepository.getRoundState(__classPrivateFieldGet(this, _Consensus_blockNumber, "f"), __classPrivateFieldGet(this, _Consensus_round, "f")).logPrevotes();
|
|
300
304
|
__classPrivateFieldSet(this, _Consensus_step, Contracts.Consensus.Step.Precommit, "f");
|
|
301
305
|
await this.precommit();
|
|
302
306
|
});
|
|
303
307
|
}
|
|
304
|
-
async onTimeoutPrecommit(
|
|
308
|
+
async onTimeoutPrecommit(blockNumber, round) {
|
|
305
309
|
await __classPrivateFieldGet(this, _Consensus_handlerLock, "f").runExclusive(async () => {
|
|
306
|
-
if (__classPrivateFieldGet(this,
|
|
310
|
+
if (__classPrivateFieldGet(this, _Consensus_blockNumber, "f") !== blockNumber || __classPrivateFieldGet(this, _Consensus_round, "f") !== round) {
|
|
307
311
|
return;
|
|
308
312
|
}
|
|
309
|
-
this.logger.info(`Timeout to precommit ${__classPrivateFieldGet(this,
|
|
310
|
-
this.roundStateRepository.getRoundState(__classPrivateFieldGet(this,
|
|
311
|
-
this.roundStateRepository.getRoundState(__classPrivateFieldGet(this,
|
|
313
|
+
this.logger.info(`Timeout to precommit ${__classPrivateFieldGet(this, _Consensus_blockNumber, "f")}/${__classPrivateFieldGet(this, _Consensus_round, "f")} expired`);
|
|
314
|
+
this.roundStateRepository.getRoundState(__classPrivateFieldGet(this, _Consensus_blockNumber, "f"), __classPrivateFieldGet(this, _Consensus_round, "f")).logPrevotes();
|
|
315
|
+
this.roundStateRepository.getRoundState(__classPrivateFieldGet(this, _Consensus_blockNumber, "f"), __classPrivateFieldGet(this, _Consensus_round, "f")).logPrecommits();
|
|
312
316
|
await this.startRound(__classPrivateFieldGet(this, _Consensus_round, "f") + 1);
|
|
313
317
|
});
|
|
314
318
|
}
|
|
@@ -324,8 +328,8 @@ let Consensus = class Consensus {
|
|
|
324
328
|
__classPrivateFieldSet(this, _Consensus_proposalPromise, __classPrivateFieldGet(this, _Consensus_instances, "m", _Consensus_makeProposal).call(this, roundState, registeredProposer), "f");
|
|
325
329
|
}
|
|
326
330
|
async prevote(value) {
|
|
327
|
-
const roundState = this.roundStateRepository.getRoundState(__classPrivateFieldGet(this,
|
|
328
|
-
for (const validator of this.validatorSet.
|
|
331
|
+
const roundState = this.roundStateRepository.getRoundState(__classPrivateFieldGet(this, _Consensus_blockNumber, "f"), __classPrivateFieldGet(this, _Consensus_round, "f"));
|
|
332
|
+
for (const validator of this.validatorSet.getRoundValidators()) {
|
|
329
333
|
const localValidator = this.validatorsRepository.getValidator(validator.blsPublicKey);
|
|
330
334
|
if (localValidator === undefined) {
|
|
331
335
|
continue;
|
|
@@ -334,13 +338,13 @@ let Consensus = class Consensus {
|
|
|
334
338
|
if (roundState.hasPrevote(validatorIndex)) {
|
|
335
339
|
continue;
|
|
336
340
|
}
|
|
337
|
-
const prevote = await localValidator.prevote(validatorIndex, __classPrivateFieldGet(this,
|
|
341
|
+
const prevote = await localValidator.prevote(validatorIndex, __classPrivateFieldGet(this, _Consensus_blockNumber, "f"), __classPrivateFieldGet(this, _Consensus_round, "f"), value);
|
|
338
342
|
void this.prevoteProcessor.process(prevote);
|
|
339
343
|
}
|
|
340
344
|
}
|
|
341
345
|
async precommit(value) {
|
|
342
|
-
const roundState = this.roundStateRepository.getRoundState(__classPrivateFieldGet(this,
|
|
343
|
-
for (const validator of this.validatorSet.
|
|
346
|
+
const roundState = this.roundStateRepository.getRoundState(__classPrivateFieldGet(this, _Consensus_blockNumber, "f"), __classPrivateFieldGet(this, _Consensus_round, "f"));
|
|
347
|
+
for (const validator of this.validatorSet.getRoundValidators()) {
|
|
344
348
|
const localValidator = this.validatorsRepository.getValidator(validator.blsPublicKey);
|
|
345
349
|
if (localValidator === undefined) {
|
|
346
350
|
continue;
|
|
@@ -349,12 +353,12 @@ let Consensus = class Consensus {
|
|
|
349
353
|
if (roundState.hasPrecommit(validatorIndex)) {
|
|
350
354
|
continue;
|
|
351
355
|
}
|
|
352
|
-
const precommit = await localValidator.precommit(validatorIndex, __classPrivateFieldGet(this,
|
|
356
|
+
const precommit = await localValidator.precommit(validatorIndex, __classPrivateFieldGet(this, _Consensus_blockNumber, "f"), __classPrivateFieldGet(this, _Consensus_round, "f"), value);
|
|
353
357
|
void this.precommitProcessor.process(precommit);
|
|
354
358
|
}
|
|
355
359
|
}
|
|
356
360
|
};
|
|
357
|
-
|
|
361
|
+
_Consensus_blockNumber = new WeakMap();
|
|
358
362
|
_Consensus_round = new WeakMap();
|
|
359
363
|
_Consensus_step = new WeakMap();
|
|
360
364
|
_Consensus_lockedValue = new WeakMap();
|
|
@@ -368,7 +372,7 @@ _Consensus_roundStartTime = new WeakMap();
|
|
|
368
372
|
_Consensus_handlerLock = new WeakMap();
|
|
369
373
|
_Consensus_instances = new WeakSet();
|
|
370
374
|
_Consensus_isInvalidRoundState = function _Consensus_isInvalidRoundState(roundState) {
|
|
371
|
-
if (roundState.
|
|
375
|
+
if (roundState.blockNumber !== __classPrivateFieldGet(this, _Consensus_blockNumber, "f")) {
|
|
372
376
|
return true;
|
|
373
377
|
}
|
|
374
378
|
if (roundState.round !== __classPrivateFieldGet(this, _Consensus_round, "f")) {
|
|
@@ -380,35 +384,33 @@ _Consensus_makeProposal = async function _Consensus_makeProposal(roundState, reg
|
|
|
380
384
|
if (__classPrivateFieldGet(this, _Consensus_validValue, "f")) {
|
|
381
385
|
const block = __classPrivateFieldGet(this, _Consensus_validValue, "f").getBlock();
|
|
382
386
|
const lockProof = await __classPrivateFieldGet(this, _Consensus_validValue, "f").aggregatePrevotes();
|
|
383
|
-
this.logger.info(`Proposing valid block ${__classPrivateFieldGet(this,
|
|
387
|
+
this.logger.info(`Proposing valid block ${__classPrivateFieldGet(this, _Consensus_blockNumber, "f")}/${__classPrivateFieldGet(this, _Consensus_round, "f")} from round ${this.getValidRound()} with block hash: ${block.data.hash}`);
|
|
384
388
|
return await registeredProposer.propose(this.validatorSet.getValidatorIndexByWalletAddress(roundState.proposer.address), __classPrivateFieldGet(this, _Consensus_round, "f"), __classPrivateFieldGet(this, _Consensus_validValue, "f").round, block, lockProof);
|
|
385
389
|
}
|
|
386
390
|
const block = await registeredProposer.prepareBlock(roundState.proposer.address, __classPrivateFieldGet(this, _Consensus_round, "f"), this.scheduler.getNextBlockTimestamp(__classPrivateFieldGet(this, _Consensus_roundStartTime, "f")));
|
|
387
|
-
this.logger.info(`Proposing new block ${__classPrivateFieldGet(this,
|
|
391
|
+
this.logger.info(`Proposing new block ${__classPrivateFieldGet(this, _Consensus_blockNumber, "f")}/${__classPrivateFieldGet(this, _Consensus_round, "f")} with block hash: ${block.data.hash}`);
|
|
388
392
|
void this.eventDispatcher.dispatch(Events.BlockEvent.Forged, block.data);
|
|
389
393
|
return registeredProposer.propose(this.validatorSet.getValidatorIndexByWalletAddress(roundState.proposer.address), __classPrivateFieldGet(this, _Consensus_round, "f"), undefined, block);
|
|
390
394
|
};
|
|
391
395
|
_Consensus_bootstrap = async function _Consensus_bootstrap() {
|
|
396
|
+
__classPrivateFieldSet(this, _Consensus_blockNumber, this.stateStore.getLastBlock().data.number + 1, "f");
|
|
392
397
|
const state = await this.bootstrapper.run();
|
|
393
|
-
if (state
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
this.logger.warning(`Skipping state restore, because stored height is ${state.height}, but should be ${this.stateStore.getLastBlock().data.height + 1}`);
|
|
398
|
+
if (state) {
|
|
399
|
+
if (state.blockNumber === __classPrivateFieldGet(this, _Consensus_blockNumber, "f")) {
|
|
400
|
+
__classPrivateFieldSet(this, _Consensus_step, state.step, "f");
|
|
401
|
+
__classPrivateFieldSet(this, _Consensus_round, state.round, "f");
|
|
402
|
+
__classPrivateFieldSet(this, _Consensus_lockedValue, state.lockedValue, "f");
|
|
403
|
+
__classPrivateFieldSet(this, _Consensus_validValue, state.validValue, "f");
|
|
404
|
+
}
|
|
405
|
+
else {
|
|
406
|
+
this.logger.warning(`Skipping state restore, because stored block number is ${state.blockNumber}, but should be ${__classPrivateFieldGet(this, _Consensus_blockNumber, "f")}`);
|
|
403
407
|
this.roundStateRepository.clear();
|
|
404
408
|
}
|
|
405
|
-
const lastBlock = this.stateStore.getLastBlock();
|
|
406
|
-
__classPrivateFieldSet(this, _Consensus_height, lastBlock.data.height + 1, "f");
|
|
407
409
|
}
|
|
408
|
-
if (__classPrivateFieldGet(this,
|
|
409
|
-
throw new Error(`bootstrapped
|
|
410
|
+
if (__classPrivateFieldGet(this, _Consensus_blockNumber, "f") !== this.configuration.getHeight()) {
|
|
411
|
+
throw new Error(`bootstrapped block number ${__classPrivateFieldGet(this, _Consensus_blockNumber, "f")} does not match configuration block number ${this.configuration.getHeight()}`);
|
|
410
412
|
}
|
|
411
|
-
this.logger.info(`Completed consensus bootstrap for ${__classPrivateFieldGet(this,
|
|
413
|
+
this.logger.info(`Completed consensus bootstrap for ${__classPrivateFieldGet(this, _Consensus_blockNumber, "f")}/${__classPrivateFieldGet(this, _Consensus_round, "f")}/${this.stateStore.getTotalRound()}`);
|
|
412
414
|
await this.eventDispatcher.dispatch(Events.ConsensusEvent.Bootstrapped, this.getState());
|
|
413
415
|
};
|
|
414
416
|
_Consensus_processProposal = async function _Consensus_processProposal(roundState) {
|