1717import * as chai from "chai" ;
1818import { expect } from "chai" ;
1919import * as chaiAsPromised from "chai-as-promised" ;
20+ import { SDK } from "codechain-sdk" ;
2021import * as stake from "codechain-stakeholder-sdk" ;
2122import * as fs from "fs" ;
2223import "mocha" ;
2324import * as path from "path" ;
2425
2526import mkdirp = require( "mkdirp" ) ;
2627import { validators } from "../../../tendermint.dynval/constants" ;
28+ import { faucetAddress , faucetSecret } from "../../helper/constants" ;
2729import { PromiseExpect } from "../../helper/promise" ;
28- import CodeChain from "../../helper/spawn" ;
30+ import CodeChain , { Signer } from "../../helper/spawn" ;
2931import { setTermTestTimeout , withNodes } from "../setup" ;
3032
3133chai . use ( chaiAsPromised ) ;
@@ -36,6 +38,7 @@ const SNAPSHOT_PATH = `${__dirname}/../../../../snapshot/`;
3638describe ( "Snapshot for Tendermint with Dynamic Validator" , function ( ) {
3739 const promiseExpect = new PromiseExpect ( ) ;
3840 const snapshotValidators = validators . slice ( 0 , 3 ) ;
41+ const freshNodeValidator = validators [ 3 ] ;
3942 const { nodes } = withNodes ( this , {
4043 promiseExpect,
4144 overrideParams : {
@@ -82,9 +85,77 @@ describe("Snapshot for Tendermint with Dynamic Validator", function() {
8285 ) . to . satisfy ( fs . existsSync ) ;
8386 } ) ;
8487
88+ it ( "should be able to boot with the snapshot" , async function ( ) {
89+ const termWaiter = setTermTestTimeout ( this , {
90+ terms : 3
91+ } ) ;
92+ const termMetadata1 = await termWaiter . waitNodeUntilTerm ( nodes [ 0 ] , {
93+ target : 2 ,
94+ termPeriods : 1
95+ } ) ;
96+ const snapshotBlock = await getSnapshotBlock ( nodes [ 0 ] , termMetadata1 ) ;
97+ await makeItValidator ( nodes [ 0 ] , freshNodeValidator ) ;
98+ const snapshotPath = fs . mkdtempSync ( SNAPSHOT_PATH ) ;
99+ const node = new CodeChain ( {
100+ chain : `${ __dirname } /../../scheme/tendermint-dynval.json` ,
101+ argv : [
102+ "--engine-signer" ,
103+ freshNodeValidator . platformAddress . toString ( ) ,
104+ "--password-path" ,
105+ `test/tendermint.dynval/${ freshNodeValidator . platformAddress . value } /password.json` ,
106+ "--force-sealing" ,
107+ "--snapshot-path" ,
108+ snapshotPath ,
109+ "--config" ,
110+ SNAPSHOT_CONFIG ,
111+ "--snapshot-hash" ,
112+ snapshotBlock . hash . toString ( ) ,
113+ "--snapshot-number" ,
114+ snapshotBlock . number . toString ( )
115+ ] ,
116+ additionalKeysPath : `tendermint.dynval/${ freshNodeValidator . platformAddress . value } /keys`
117+ } ) ;
118+ try {
119+ await node . start ( ) ;
120+ await node . connect ( nodes [ 0 ] ) ;
121+ await termWaiter . waitNodeUntilTerm ( node , {
122+ target : 4 ,
123+ termPeriods : 2
124+ } ) ;
125+
126+ await freshValidatorCheck ( nodes [ 0 ] . sdk ) ;
127+
128+ expect ( await node . sdk . rpc . chain . getBlock ( snapshotBlock . number - 1 ) )
129+ . to . be . null ;
130+ expect ( await node . sdk . rpc . chain . getBlock ( snapshotBlock . number ) ) . not
131+ . to . be . null ;
132+ // Check that the freshNodeValidator is still a validator & make sure it doesn't have a block/header before termMetadata1.
133+ } catch ( e ) {
134+ node . keepLogs ( ) ;
135+ throw e ;
136+ } finally {
137+ await node . clean ( ) ;
138+ }
139+ } ) ;
140+
85141 afterEach ( async function ( ) {
86142 promiseExpect . checkFulfilled ( ) ;
87143 } ) ;
144+
145+ async function freshValidatorCheck ( sdk : SDK ) {
146+ const blockNumber = await sdk . rpc . chain . getBestBlockNumber ( ) ;
147+ const termMedata = await stake . getTermMetadata ( sdk , blockNumber ) ;
148+ const currentTermInitialBlockNumber =
149+ termMedata ! . lastTermFinishedBlockNumber + 1 ;
150+ const validatorsAfter = ( await stake . getPossibleAuthors (
151+ sdk ,
152+ currentTermInitialBlockNumber
153+ ) ) ! . map ( platformAddr => platformAddr . toString ( ) ) ;
154+
155+ expect ( validatorsAfter ) . and . contains (
156+ freshNodeValidator . platformAddress . toString ( )
157+ ) ;
158+ }
88159} ) ;
89160
90161async function getSnapshotBlock (
@@ -95,3 +166,44 @@ async function getSnapshotBlock(
95166 await node . waitBlockNumber ( blockNumber ) ;
96167 return ( await node . sdk . rpc . chain . getBlock ( blockNumber ) ) ! ;
97168}
169+
170+ async function makeItValidator ( node : CodeChain , freshNodeValidator : Signer ) {
171+ const faucetSeq = await node . sdk . rpc . chain . getSeq ( faucetAddress ) ;
172+ const payTx = node . sdk . core
173+ . createPayTransaction ( {
174+ recipient : freshNodeValidator . platformAddress ,
175+ quantity : 200000000
176+ } )
177+ . sign ( {
178+ secret : faucetSecret ,
179+ seq : faucetSeq ,
180+ fee : 10
181+ } ) ;
182+ await node . waitForTx ( await node . sdk . rpc . chain . sendSignedTransaction ( payTx ) ) ;
183+ const selfNominateTx = stake
184+ . createSelfNominateTransaction ( node . sdk , 10000000 , "" )
185+ . sign ( {
186+ secret : freshNodeValidator . privateKey ,
187+ seq : await node . sdk . rpc . chain . getSeq (
188+ freshNodeValidator . platformAddress
189+ ) ,
190+ fee : 10
191+ } ) ;
192+ await node . waitForTx (
193+ await node . sdk . rpc . chain . sendSignedTransaction ( selfNominateTx )
194+ ) ;
195+ const delegateTx = stake
196+ . createDelegateCCSTransaction (
197+ node . sdk ,
198+ freshNodeValidator . platformAddress ,
199+ 10000
200+ )
201+ . sign ( {
202+ secret : faucetSecret ,
203+ seq : faucetSeq + 1 ,
204+ fee : 10
205+ } ) ;
206+ await node . waitForTx (
207+ await node . sdk . rpc . chain . sendSignedTransaction ( delegateTx )
208+ ) ;
209+ }
0 commit comments