diff --git a/core/src/miner/miner.rs b/core/src/miner/miner.rs index 88dda2a26a..76066ea65a 100644 --- a/core/src/miner/miner.rs +++ b/core/src/miner/miner.rs @@ -43,7 +43,7 @@ use std::iter::FromIterator; use std::ops::Range; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; -use std::time::{Duration, Instant}; +use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH}; /// Configures the behaviour of the miner. #[derive(Debug, PartialEq)] @@ -530,6 +530,14 @@ impl MinerService for Miner { } }; + if std::env::var("RUN_ON_TEST").is_ok() { + let now = SystemTime::now().duration_since(UNIX_EPOCH).expect("There is no time machine.").as_secs(); + if block.header().timestamp() > now { + let delta = block.header().timestamp() - now; + std::thread::sleep(std::time::Duration::from_secs(delta)); + } + } + if self.engine.seals_internally() { ctrace!(MINER, "update_sealing: engine indicates internal sealing"); if self.import_block_internally(chain, block) { diff --git a/test/package.json b/test/package.json index fc36a4e4b4..c40e5ca3f2 100644 --- a/test/package.json +++ b/test/package.json @@ -25,10 +25,11 @@ "test-mock": "mocha -r ts-node/register --timeout 5000 \"src/helper/mock/**/*.test.ts\"", "tendermint-test-local": "cargo build --release && NODE_ENV=production ts-node src/tendermint.test/local.ts", "tendermint-test-remote": "NODE_ENV=production ts-node src/tendermint.test/remote.ts", - "lint": "tslint -p . && prettier 'src/**/*.{ts, json}' -l", + "lint": "tsc -p . --noEmit && tslint -p . && prettier 'src/**/*.{ts, json}' -l", "fmt": "tslint -p . --fix && prettier 'src/**/*.{ts, json}' --write" }, "devDependencies": { + "@types/bn.js": "^4.11.6", "@types/chai": "^4.2.5", "@types/chai-as-promised": "^7.1.2", "@types/crypto-js": "^3.1.44", diff --git a/test/src/e2e.dynval/2/snapshot.test.ts b/test/src/e2e.dynval/2/snapshot.test.ts index 54e62a3a75..445280386f 100644 --- a/test/src/e2e.dynval/2/snapshot.test.ts +++ b/test/src/e2e.dynval/2/snapshot.test.ts @@ -22,7 +22,6 @@ import * as fs from "fs"; import "mocha"; import * as path from "path"; import * as stake from "../../stakeholder"; -import * as mkdirp from "mkdirp"; import { validators } from "../../../tendermint.dynval/constants"; import { faucetAddress, faucetSecret } from "../../helper/constants"; import { PromiseExpect } from "../../helper/promise"; @@ -33,7 +32,6 @@ import { H256 } from "../../primitives/src"; chai.use(chaiAsPromised); const SNAPSHOT_CONFIG = `${__dirname}/../../../tendermint.dynval/snapshot-config.yml`; -const SNAPSHOT_PATH = `${__dirname}/../../../../snapshot/`; describe("Snapshot for Tendermint with Dynamic Validator", function() { const promiseExpect = new PromiseExpect(); @@ -50,18 +48,8 @@ describe("Snapshot for Tendermint with Dynamic Validator", function() { deposit: 10_000_000 - index // tie-breaker })), modify: () => { - mkdirp.sync(SNAPSHOT_PATH); - const snapshotPath = fs.mkdtempSync(SNAPSHOT_PATH); return { - additionalArgv: [ - "--snapshot-path", - snapshotPath, - "--config", - SNAPSHOT_CONFIG - ], - nodeAdditionalProperties: { - snapshotPath - } + additionalArgv: ["--config", SNAPSHOT_CONFIG] }; } }); @@ -94,7 +82,6 @@ describe("Snapshot for Tendermint with Dynamic Validator", function() { }); const snapshotBlock = await getSnapshotBlock(nodes[0], termMetadata1); await makeItValidator(nodes[0], freshNodeValidator); - const snapshotPath = fs.mkdtempSync(SNAPSHOT_PATH); const node = new CodeChain({ chain: `${__dirname}/../../scheme/tendermint-dynval.json`, argv: [ @@ -103,8 +90,6 @@ describe("Snapshot for Tendermint with Dynamic Validator", function() { "--password-path", `test/tendermint.dynval/${freshNodeValidator.address.value}/password.json`, "--force-sealing", - "--snapshot-path", - snapshotPath, "--config", SNAPSHOT_CONFIG, "--snapshot-hash", diff --git a/test/src/e2e.dynval/setup.ts b/test/src/e2e.dynval/setup.ts index 858a53c88c..aeb21f363f 100644 --- a/test/src/e2e.dynval/setup.ts +++ b/test/src/e2e.dynval/setup.ts @@ -44,27 +44,25 @@ interface ValidatorConfig { autoSelfNominate?: boolean; } -interface NodePropertyModifier { +interface NodePropertyModifier { additionalArgv: string[]; - nodeAdditionalProperties: T; } -export function withNodes( +export function withNodes( suite: Suite, options: { promiseExpect: PromiseExpect; validators: ValidatorConfig[]; overrideParams?: Partial; onBeforeEnable?: (nodes: CodeChain[]) => Promise; - modify?: (signer: Signer, index: number) => NodePropertyModifier; + modify?: (signer: Signer, index: number) => NodePropertyModifier; } ) { - const nodes: (CodeChain & T)[] = []; + const nodes: CodeChain[] = []; const { overrideParams = {}, modify = () => ({ - additionalArgv: [], - nodeAdditionalProperties: {} as T + additionalArgv: [] }) } = options; const initialParams = { @@ -110,13 +108,13 @@ export function findNode(nodes: CodeChain[], signer: Signer) { ); } -async function createNodes(options: { +async function createNodes(options: { promiseExpect: PromiseExpect; validators: ValidatorConfig[]; initialParams: CommonParams; onBeforeEnable?: (nodes: CodeChain[]) => Promise; - modify: (signer: Signer, index: number) => NodePropertyModifier; -}): Promise<(CodeChain & T)[]> { + modify: (signer: Signer, index: number) => NodePropertyModifier; +}): Promise { const chain = `${__dirname}/../scheme/tendermint-dynval.json`; const { promiseExpect, validators, initialParams, modify } = options; @@ -140,7 +138,7 @@ async function createNodes(options: { }); } - const nodes: (CodeChain & T)[] = []; + const nodes: CodeChain[] = []; for (let i = 0; i < validators.length; i++) { const { signer: validator } = validators[i]; const argv = [ @@ -167,7 +165,7 @@ async function createNodes(options: { argv: [...argv, ...modifier.additionalArgv], additionalKeysPath: `tendermint.dynval/${validator.address.value}/keys` }); - nodes[i] = Object.assign(node, modifier.nodeAdditionalProperties); + nodes[i] = node; nodes[i].signer = validator; } let bootstrapFailed = false; diff --git a/test/src/e2e/snapshot.test.ts b/test/src/e2e/snapshot.test.ts index 0127529d9d..b6467ae2e8 100644 --- a/test/src/e2e/snapshot.test.ts +++ b/test/src/e2e/snapshot.test.ts @@ -22,18 +22,14 @@ import * as path from "path"; import { aliceAddress } from "../helper/constants"; import CodeChain from "../helper/spawn"; -const SNAPSHOT_PATH = `${__dirname}/../../../snapshot/`; - describe("Snapshot", async function() { let node: CodeChain; before(async function() { - node = new CodeChain({ - argv: ["--snapshot-path", SNAPSHOT_PATH] - }); + node = new CodeChain(); await node.start(); }); - it("can make a snapshot when it is requsted with devel rpc", async function() { + it("can make a snapshot when it is requested with devel rpc", async function() { const pay = await node.sendPayTx({ quantity: 100, recipient: aliceAddress @@ -50,7 +46,11 @@ describe("Snapshot", async function() { blockHash }))!.stateRoot; expect( - path.join(SNAPSHOT_PATH, blockHash.substr(2), stateRoot.substr(2)) + path.join( + node.snapshotPath, + blockHash.substr(2), + stateRoot.substr(2) + ) ).to.satisfies(fs.existsSync); }); diff --git a/test/src/e2e/staking.test.ts b/test/src/e2e/staking.test.ts index d86bc4356e..cc7602d84f 100644 --- a/test/src/e2e/staking.test.ts +++ b/test/src/e2e/staking.test.ts @@ -861,7 +861,7 @@ describe("Staking", function() { address: validator1Address.toString() }))!; expect(validator1Balance).to.be.deep.equal(oldValidator1Balance); - }); + }).timeout(60_000); afterEach(async function() { if (this.currentTest!.state === "failed") { diff --git a/test/src/helper/mock/example/send-tx.ts b/test/src/helper/mock/example/send-tx.ts index bb761433b3..02dbcf7730 100644 --- a/test/src/helper/mock/example/send-tx.ts +++ b/test/src/helper/mock/example/send-tx.ts @@ -1,5 +1,5 @@ import { Mock } from ".."; -import * as SDK from "../../../sdk"; +import { SDK } from "../../../sdk"; async function sendTransaction() { const mock = new Mock("0.0.0.0", 3485, "tc"); @@ -7,20 +7,19 @@ async function sendTransaction() { await mock.establish(); const sdk = new SDK({ - server: process.env.CODECHAIN_RPC_HTTP || "http://localhost:8080", networkId: process.env.CODECHAIN_NETWORK_ID || "tc" }); const ACCOUNT_SECRET = process.env.ACCOUNT_SECRET || "9af28f6fd6a1170dbee2cb8c34abab0408e6d811d212cdcde23f72473eb0d97ad7a6d266837c1c591383b90d835068b9ed58dd3bcebd6e285911f58e40ce413c"; const unsigned = sdk.core.createPayTransaction({ - recipient: "tccqruq09sfgax77nj4gukjcuq69uzeyv0jcs7vzngg", - amount: 10000 + recipient: "fys3db1kOrI_rXyaTx9U2_RP-SlNK1q0LRXxYeQGBI1av35drZQtc0", + quantity: 10000 }); const signed = unsigned.sign({ secret: ACCOUNT_SECRET, fee: 10, - nonce: 0 + seq: 0 }); await mock.sendEncodedTransaction([signed.toEncodeObject()]); diff --git a/test/src/helper/spawn.ts b/test/src/helper/spawn.ts index b58a752c5f..2d9eb9082d 100644 --- a/test/src/helper/spawn.ts +++ b/test/src/helper/spawn.ts @@ -72,6 +72,7 @@ export default class CodeChain { private readonly _testFramework: SDK; private readonly _localKeyStorePath: string; private readonly _dbPath: string; + private readonly _snapshotPath: string; private readonly _ipcPath: string; private readonly _keysPath: string; private readonly _logFile: string; @@ -111,6 +112,9 @@ export default class CodeChain { public get dbPath(): string { return this._dbPath; } + public get snapshotPath(): string { + return this._snapshotPath; + } public get ipcPath(): string { return this._ipcPath; } @@ -164,7 +168,9 @@ export default class CodeChain { mkdirp.sync(`${projectRoot}/db/`); mkdirp.sync(`${projectRoot}/keys/`); mkdirp.sync(`${projectRoot}/test/log/`); + mkdirp.sync(`${projectRoot}/snapshot/`); this._dbPath = mkdtempSync(`${projectRoot}/db/`); + this._snapshotPath = mkdtempSync(`${projectRoot}/db/`); this._ipcPath = `/tmp/jsonrpc.${new Date() .toISOString() .replace(/[-:.]/g, "_")}.${this.id}.ipc`; @@ -244,6 +250,8 @@ export default class CodeChain { this.chain, "--db-path", this.dbPath, + "--snapshot-path", + this.snapshotPath, "--keys-path", this.keysPath, "--no-ws", @@ -257,6 +265,7 @@ export default class CodeChain { { cwd: projectRoot, env: { + RUN_ON_TEST: "1", ...process.env, ...this.env } diff --git a/test/src/sdk/index.ts b/test/src/sdk/index.ts index b58c5e5959..e65816447d 100644 --- a/test/src/sdk/index.ts +++ b/test/src/sdk/index.ts @@ -39,7 +39,6 @@ class SDK { private _networkId: string; /** - * @param params.server HTTP RPC server address * @param params.keyStoreType Specify the type of the keystore. The default value is "local". It creates keystore.db file on the working directory. * @param params.networkId The network id of CodeChain. The default value is "tc" (testnet) */ diff --git a/test/yarn.lock b/test/yarn.lock index 8ca2337eea..b24d6769ac 100644 --- a/test/yarn.lock +++ b/test/yarn.lock @@ -23,6 +23,13 @@ resolved "https://registry.yarnpkg.com/@types/bluebird/-/bluebird-3.5.30.tgz#ee034a0eeea8b84ed868b1aa60d690b08a6cfbc5" integrity sha512-8LhzvcjIoqoi1TghEkRMkbbmM+jhHnBokPGkJWjclMK+Ks0MxEBow3/p2/iFTZ+OIbJHQDSfpgdZEb+af3gfVw== +"@types/bn.js@^4.11.6": + version "4.11.6" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" + integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== + dependencies: + "@types/node" "*" + "@types/caseless@*": version "0.12.2" resolved "https://registry.yarnpkg.com/@types/caseless/-/caseless-0.12.2.tgz#f65d3d6389e01eeb458bd54dc8f52b95a9463bc8"