diff --git a/test/src/e2e.dynval/2/snapshot.test.ts b/test/src/e2e.dynval/2/snapshot.test.ts index bb548d4aef..bb706a2c45 100644 --- a/test/src/e2e.dynval/2/snapshot.test.ts +++ b/test/src/e2e.dynval/2/snapshot.test.ts @@ -24,8 +24,9 @@ import * as path from "path"; import mkdirp = require("mkdirp"); import { validators } from "../../../tendermint.dynval/constants"; +import { faucetAddress, faucetSecret } from "../../helper/constants"; import { PromiseExpect } from "../../helper/promise"; -import CodeChain from "../../helper/spawn"; +import CodeChain, { Signer } from "../../helper/spawn"; import { setTermTestTimeout, withNodes } from "../setup"; chai.use(chaiAsPromised); @@ -36,6 +37,7 @@ const SNAPSHOT_PATH = `${__dirname}/../../../../snapshot/`; describe("Snapshot for Tendermint with Dynamic Validator", function() { const promiseExpect = new PromiseExpect(); const snapshotValidators = validators.slice(0, 3); + const freshNodeValidator = validators[3]; const { nodes } = withNodes(this, { promiseExpect, overrideParams: { @@ -82,6 +84,53 @@ describe("Snapshot for Tendermint with Dynamic Validator", function() { ).to.satisfy(fs.existsSync); }); + it("should be able to boot with the snapshot", async function() { + const termWaiter = setTermTestTimeout(this, { + terms: 3 + }); + const termMetadata1 = await termWaiter.waitNodeUntilTerm(nodes[0], { + target: 2, + termPeriods: 1 + }); + 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: [ + "--engine-signer", + freshNodeValidator.platformAddress.toString(), + "--password-path", + `test/tendermint.dynval/${freshNodeValidator.platformAddress.value}/password.json`, + "--force-sealing", + "--snapshot-path", + snapshotPath, + "--config", + SNAPSHOT_CONFIG, + "--snapshot-hash", + snapshotBlock.hash.toString(), + "--snapshot-number", + snapshotBlock.number.toString() + ], + additionalKeysPath: `tendermint.dynval/${freshNodeValidator.platformAddress.value}/keys` + }); + try { + await node.start(); + await node.connect(nodes[0]); + await termWaiter.waitNodeUntilTerm(node, { + target: 4, + termPeriods: 2 + }); + + // Check that the freshNodeValidator is still a validator & make sure it doesn't have a block/header before termMetadata1. + } catch (e) { + node.keepLogs(); + throw e; + } finally { + await node.clean(); + } + }); + afterEach(async function() { promiseExpect.checkFulfilled(); }); @@ -95,3 +144,44 @@ async function getSnapshotBlock( await node.waitBlockNumber(blockNumber); return (await node.sdk.rpc.chain.getBlock(blockNumber))!; } + +async function makeItValidator(node: CodeChain, freshNodeValidator: Signer) { + const faucetSeq = await node.sdk.rpc.chain.getSeq(faucetAddress); + const payTx = node.sdk.core + .createPayTransaction({ + recipient: freshNodeValidator.platformAddress, + quantity: 200000000 + }) + .sign({ + secret: faucetSecret, + seq: faucetSeq, + fee: 10 + }); + await node.waitForTx(await node.sdk.rpc.chain.sendSignedTransaction(payTx)); + const selfNominateTx = stake + .createSelfNominateTransaction(node.sdk, 10000000, "") + .sign({ + secret: freshNodeValidator.privateKey, + seq: await node.sdk.rpc.chain.getSeq( + freshNodeValidator.platformAddress + ), + fee: 10 + }); + await node.waitForTx( + await node.sdk.rpc.chain.sendSignedTransaction(selfNominateTx) + ); + const delegateTx = stake + .createDelegateCCSTransaction( + node.sdk, + freshNodeValidator.platformAddress, + 5000 + ) + .sign({ + secret: faucetSecret, + seq: faucetSeq + 1, + fee: 10 + }); + await node.waitForTx( + await node.sdk.rpc.chain.sendSignedTransaction(delegateTx) + ); +}