17
17
import * as chai from "chai" ;
18
18
import { expect } from "chai" ;
19
19
import * as chaiAsPromised from "chai-as-promised" ;
20
+ import { SDK } from "codechain-sdk" ;
20
21
import * as stake from "codechain-stakeholder-sdk" ;
21
22
import * as fs from "fs" ;
22
23
import "mocha" ;
23
24
import * as path from "path" ;
24
25
25
26
import mkdirp = require( "mkdirp" ) ;
26
27
import { validators } from "../../../tendermint.dynval/constants" ;
28
+ import { faucetAddress , faucetSecret } from "../../helper/constants" ;
27
29
import { PromiseExpect } from "../../helper/promise" ;
28
- import CodeChain from "../../helper/spawn" ;
30
+ import CodeChain , { Signer } from "../../helper/spawn" ;
29
31
import { setTermTestTimeout , withNodes } from "../setup" ;
30
32
31
33
chai . use ( chaiAsPromised ) ;
@@ -36,6 +38,7 @@ const SNAPSHOT_PATH = `${__dirname}/../../../../snapshot/`;
36
38
describe ( "Snapshot for Tendermint with Dynamic Validator" , function ( ) {
37
39
const promiseExpect = new PromiseExpect ( ) ;
38
40
const snapshotValidators = validators . slice ( 0 , 3 ) ;
41
+ const freshNodeValidator = validators [ 3 ] ;
39
42
const { nodes } = withNodes ( this , {
40
43
promiseExpect,
41
44
overrideParams : {
@@ -82,9 +85,77 @@ describe("Snapshot for Tendermint with Dynamic Validator", function() {
82
85
) . to . satisfy ( fs . existsSync ) ;
83
86
} ) ;
84
87
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
+
85
141
afterEach ( async function ( ) {
86
142
promiseExpect . checkFulfilled ( ) ;
87
143
} ) ;
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
+ }
88
159
} ) ;
89
160
90
161
async function getSnapshotBlock (
@@ -95,3 +166,44 @@ async function getSnapshotBlock(
95
166
await node . waitBlockNumber ( blockNumber ) ;
96
167
return ( await node . sdk . rpc . chain . getBlock ( blockNumber ) ) ! ;
97
168
}
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