Skip to content

Commit 9df84ea

Browse files
committed
Add snapshot sync test with Tendermint dynamic validator
1 parent d9c08cc commit 9df84ea

File tree

3 files changed

+200
-10
lines changed

3 files changed

+200
-10
lines changed
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// Copyright 2019 Kodebox, Inc.
2+
// This file is part of CodeChain.
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Affero General Public License as
6+
// published by the Free Software Foundation, either version 3 of the
7+
// License, or (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Affero General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Affero General Public License
15+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
17+
import * as chai from "chai";
18+
import { expect } from "chai";
19+
import * as chaiAsPromised from "chai-as-promised";
20+
import { SDK } from "codechain-sdk";
21+
import * as stake from "codechain-stakeholder-sdk";
22+
import * as fs from "fs";
23+
import "mocha";
24+
import * as path from "path";
25+
26+
import mkdirp = require("mkdirp");
27+
import { validators } from "../../../tendermint.dynval/constants";
28+
import { PromiseExpect } from "../../helper/promise";
29+
import { setTermTestTimeout, withNodes } from "../setup";
30+
31+
chai.use(chaiAsPromised);
32+
33+
const SNAPSHOT_CONFIG = `${__dirname}/../../../tendermint.dynval/snapshot-config.yml`;
34+
const SNAPSHOT_PATH = `${__dirname}/../../../../snapshot/`;
35+
36+
describe("Snapshot for Tendermint with Dynamic Validator", function() {
37+
const promiseExpect = new PromiseExpect();
38+
const snapshotValidators = validators.slice(0, 3);
39+
40+
describe("Snapshot", async function() {
41+
const { nodes } = withNodes(this, {
42+
promiseExpect,
43+
overrideParams: {
44+
maxNumOfValidators: 3
45+
},
46+
validators: snapshotValidators.map((signer, index) => ({
47+
signer,
48+
delegation: 5000,
49+
deposit: 10_000_000 - index // tie-breaker
50+
})),
51+
modify: () => {
52+
mkdirp.sync(SNAPSHOT_PATH);
53+
const snapshotPath = fs.mkdtempSync(SNAPSHOT_PATH);
54+
return {
55+
additionalArgv: [
56+
"--snapshot-path",
57+
snapshotPath,
58+
"--config",
59+
SNAPSHOT_CONFIG
60+
],
61+
nodeAdditionalProperties: {
62+
snapshotPath
63+
}
64+
};
65+
}
66+
});
67+
68+
it("should be exist after some time", async function() {
69+
const termWaiter = setTermTestTimeout(this, {
70+
terms: 1
71+
});
72+
await termWaiter.waitNodeUntilTerm(nodes[0], {
73+
target: 2,
74+
termPeriods: 1
75+
});
76+
const blockNumber = await nodes[0].sdk.rpc.chain.getBestBlockNumber();
77+
const termMetadata = await stake.getTermMetadata(
78+
nodes[0].sdk,
79+
blockNumber
80+
);
81+
82+
expect(termMetadata).not.to.be.null;
83+
const {
84+
currentTermId,
85+
lastTermFinishedBlockNumber
86+
} = termMetadata!;
87+
expect(currentTermId).to.be.equals(2);
88+
expect(lastTermFinishedBlockNumber).to.be.lte(blockNumber);
89+
90+
const blockHash = (await nodes[0].sdk.rpc.chain.getBlockHash(
91+
lastTermFinishedBlockNumber
92+
))!;
93+
const stateRoot = (await nodes[0].sdk.rpc.chain.getBlock(
94+
blockHash
95+
))!.stateRoot;
96+
expect(
97+
fs.existsSync(
98+
path.join(
99+
nodes[0].snapshotPath,
100+
blockHash.toString(),
101+
stateRoot.toString()
102+
)
103+
)
104+
).to.be.true;
105+
});
106+
});
107+
108+
afterEach(async function() {
109+
promiseExpect.checkFulfilled();
110+
});
111+
});

test/src/e2e.dynval/setup.ts

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,29 @@ interface ValidatorConfig {
2323
delegation?: U64Value;
2424
}
2525

26-
export function withNodes(
26+
interface NodePropertyModifier<T> {
27+
additionalArgv: string[];
28+
nodeAdditionalProperties: T;
29+
}
30+
31+
export function withNodes<T>(
2732
suite: Suite,
2833
options: {
2934
promiseExpect: PromiseExpect;
3035
validators: ValidatorConfig[];
3136
overrideParams?: Partial<CommonParams>;
3237
onBeforeEnable?: (nodes: CodeChain[]) => Promise<void>;
38+
modify?: (signer: Signer, index: number) => NodePropertyModifier<T>;
3339
}
3440
) {
35-
const nodes: CodeChain[] = [];
36-
const { overrideParams = {} } = options;
41+
const nodes: (CodeChain & T)[] = [];
42+
const {
43+
overrideParams = {},
44+
modify = () => ({
45+
additionalArgv: [],
46+
nodeAdditionalProperties: {} as T
47+
})
48+
} = options;
3749
const initialParams = {
3850
...defaultParams,
3951
...overrideParams
@@ -46,7 +58,8 @@ export function withNodes(
4658
nodes.length = 0;
4759
const newNodes = await createNodes({
4860
...options,
49-
initialParams
61+
initialParams,
62+
modify
5063
});
5164
nodes.push(...newNodes);
5265
});
@@ -79,14 +92,15 @@ export function findNode(nodes: CodeChain[], signer: Signer) {
7992
);
8093
}
8194

82-
async function createNodes(options: {
95+
async function createNodes<T>(options: {
8396
promiseExpect: PromiseExpect;
8497
validators: ValidatorConfig[];
8598
initialParams: CommonParams;
8699
onBeforeEnable?: (nodes: CodeChain[]) => Promise<void>;
87-
}): Promise<CodeChain[]> {
100+
modify: (signer: Signer, index: number) => NodePropertyModifier<T>;
101+
}): Promise<(CodeChain & T)[]> {
88102
const chain = `${__dirname}/../scheme/tendermint-dynval.json`;
89-
const { promiseExpect, validators, initialParams } = options;
103+
const { promiseExpect, validators, initialParams, modify } = options;
90104

91105
const initialNodes: CodeChain[] = [];
92106
const initialValidators = [
@@ -108,20 +122,24 @@ async function createNodes(options: {
108122
});
109123
}
110124

111-
const nodes: CodeChain[] = [];
125+
const nodes: (CodeChain & T)[] = [];
112126
for (let i = 0; i < validators.length; i++) {
113127
const { signer: validator } = validators[i];
114-
nodes[i] = new CodeChain({
128+
const modifier = modify(validator, i);
129+
const node = new CodeChain({
115130
chain,
116131
argv: [
117132
"--engine-signer",
118133
validator.platformAddress.value,
119134
"--password-path",
120135
`test/tendermint.dynval/${validator.platformAddress.value}/password.json`,
121-
"--force-sealing"
136+
"--force-sealing",
137+
...modifier.additionalArgv
122138
],
123139
additionalKeysPath: `tendermint.dynval/${validator.platformAddress.value}/keys`
124140
});
141+
142+
nodes[i] = Object.assign(node, modifier.nodeAdditionalProperties);
125143
nodes[i].setSigner(validator);
126144
}
127145
let bootstrapFailed = false;
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
[codechain]
2+
quiet = false
3+
base_path = "."
4+
chain = "solo"
5+
6+
[mining]
7+
mem_pool_mem_limit = 4 # MB
8+
mem_pool_size = 32768
9+
mem_pool_fee_bump_shift = 3 # 12.5%
10+
allow_create_shard = false
11+
notify_work = []
12+
force_sealing = false
13+
reseal_on_txs = "all"
14+
reseal_min_period = 0
15+
reseal_max_period = 120000
16+
no_reseal_timer = false
17+
work_queue_size = 20
18+
allowed_past_gap = 30000
19+
allowed_future_gap = 5000
20+
21+
[network]
22+
disable = false
23+
interface = "0.0.0.0"
24+
port = 3485
25+
max_peers = 30
26+
min_peers = 10
27+
bootstrap_addresses = []
28+
sync = true
29+
transaction_relay = true
30+
discovery = true
31+
discovery_type = "unstructured"
32+
discovery_refresh = 60000
33+
discovery_bucket_size = 10
34+
# whitelist_path = "whitelist.txt"
35+
# blacklist_path = "blacklist.txt"
36+
37+
[rpc]
38+
disable = false
39+
interface = "127.0.0.1"
40+
port = 8080
41+
42+
[ipc]
43+
disable = false
44+
path = "/tmp/jsonrpc.ipc"
45+
46+
[ws]
47+
disable = false
48+
interface = "127.0.0.1"
49+
port = 8081
50+
max_connections = 100
51+
52+
[snapshot]
53+
disable = false
54+
path = "snapshot"
55+
56+
[stratum]
57+
disable = false
58+
port = 8008
59+
60+
[email_alarm]
61+
disable = true

0 commit comments

Comments
 (0)