diff --git a/test/src/e2e.dynval/1/dv.era.test.ts b/test/src/e2e.dynval/1/dv.era.test.ts
new file mode 100644
index 0000000000..6323d6db51
--- /dev/null
+++ b/test/src/e2e.dynval/1/dv.era.test.ts
@@ -0,0 +1,86 @@
+// Copyright 2019 Kodebox, Inc.
+// This file is part of CodeChain.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+import * as chai from "chai";
+import { expect } from "chai";
+import * as chaiAsPromised from "chai-as-promised";
+import "mocha";
+
+import { validators } from "../../../tendermint.dynval/constants";
+import { PromiseExpect } from "../../helper/promise";
+import { changeParams, setTermTestTimeout, withNodes } from "../setup";
+
+chai.use(chaiAsPromised);
+
+describe("Change era", function() {
+ const promiseExpect = new PromiseExpect();
+ const { nodes, initialParams } = withNodes(this, {
+ promiseExpect,
+ overrideParams: {
+ minNumOfValidators: 3,
+ maxNumOfValidators: 5
+ },
+ validators: validators.slice(0, 3).map(signer => ({
+ signer,
+ delegation: 5_000,
+ deposit: 10_000_000
+ }))
+ });
+
+ it("should be enabled", async function() {
+ const termWaiter = setTermTestTimeout(this, {
+ terms: 3
+ });
+
+ const checkingNode = nodes[0];
+ const changeTxHash = await changeParams(checkingNode, 1, {
+ ...initialParams,
+ era: 1
+ });
+
+ await checkingNode.waitForTx(changeTxHash);
+
+ await termWaiter.waitNodeUntilTerm(checkingNode, {
+ target: 3,
+ termPeriods: 2
+ });
+ });
+
+ it("must increase monotonically", async function() {
+ const termWaiter = setTermTestTimeout(this, {
+ terms: 2
+ });
+
+ const checkingNode = nodes[0];
+ const changeTxHash = await changeParams(checkingNode, 1, {
+ ...initialParams,
+ era: 1
+ });
+
+ await checkingNode.waitForTx(changeTxHash);
+
+ await expect(
+ changeParams(checkingNode, 2, {
+ ...initialParams,
+ era: 0
+ })
+ ).eventually.rejected;
+ });
+
+ afterEach(function() {
+ promiseExpect.checkFulfilled();
+ });
+});
diff --git a/test/src/e2e.dynval/setup.ts b/test/src/e2e.dynval/setup.ts
index d9c577e824..f8cb3d227a 100644
--- a/test/src/e2e.dynval/setup.ts
+++ b/test/src/e2e.dynval/setup.ts
@@ -28,7 +28,7 @@ export function withNodes(
options: {
promiseExpect: PromiseExpect;
validators: ValidatorConfig[];
- overrideParams?: Partial;
+ overrideParams?: Partial;
onBeforeEnable?: (nodes: CodeChain[]) => Promise;
}
) {
@@ -82,7 +82,7 @@ export function findNode(nodes: CodeChain[], signer: Signer) {
async function createNodes(options: {
promiseExpect: PromiseExpect;
validators: ValidatorConfig[];
- initialParams: typeof defaultParams;
+ initialParams: CommonParams;
onBeforeEnable?: (nodes: CodeChain[]) => Promise;
}): Promise {
const chain = `${__dirname}/../scheme/tendermint-dynval.json`;
@@ -347,12 +347,14 @@ export const defaultParams = {
maxCandidateMetadataSize: 128
};
-export async function changeParams(
- node: CodeChain,
- metadataSeq: number,
- params: typeof defaultParams
-) {
- const newParams: any[] = [
+interface EraCommonParams {
+ era: number;
+}
+
+type CommonParams = typeof defaultParams & Partial;
+
+function encodeParams(params: CommonParams): any[] {
+ const result = [
params.maxExtraDataSize,
params.maxAssetSchemeMetadataSize,
params.maxTransferMetadataSize,
@@ -386,12 +388,23 @@ export async function changeParams(
params.minDeposit,
params.maxCandidateMetadataSize
];
+ if (params.era) {
+ result.push(params.era);
+ }
+ return result;
+}
+
+export async function changeParams(
+ node: CodeChain,
+ metadataSeq: number,
+ params: CommonParams
+) {
const changeParamsActionRlp: [
number,
number,
(number | string)[],
...string[]
- ] = [0xff, metadataSeq, newParams];
+ ] = [0xff, metadataSeq, encodeParams(params)];
const message = blake256(RLP.encode(changeParamsActionRlp).toString("hex"));
changeParamsActionRlp.push(
`0x${SDK.util.signEcdsa(message, faucetSecret)}`