@@ -103,6 +103,10 @@ describe('DNS Servers', function() {
103
103
wallet . addBlock ( entry , block . txs ) ;
104
104
} ) ;
105
105
106
+ miner . chain . on ( 'disconnect' , ( entry , block ) => {
107
+ wallet . removeBlock ( entry , block . txs ) ;
108
+ } ) ;
109
+
106
110
const node = new Node ( {
107
111
memory : true ,
108
112
network : network . type ,
@@ -112,12 +116,17 @@ describe('DNS Servers', function() {
112
116
httpPort : network . rpcPort + 100
113
117
} ) ;
114
118
115
- async function mineBlocks ( n ) {
119
+ async function mineBlocks ( n , tip ) {
116
120
for ( ; n > 0 ; n -- ) {
117
- // force ten minute block intervals
118
- node . network . time . offset += 60 * 10 ;
119
- const block = await miner . miner . mineBlock ( ) ;
120
- await miner . chain . add ( block ) ;
121
+ // Force twenty minute block intervals
122
+ // Why not ten? Because this ensures that even on regtest
123
+ // with its short tree interval, the "hours" digits in
124
+ // the SOA timestamp will increase every new safe root.
125
+ miner . network . time . offset += 60 * 20 ;
126
+ const block = await miner . miner . mineBlock ( tip ) ;
127
+ const entry = await miner . chain . add ( block ) ;
128
+ if ( tip )
129
+ tip = entry ;
121
130
}
122
131
await forValue ( node . chain , 'height' , miner . chain . height ) ;
123
132
}
@@ -320,6 +329,82 @@ describe('DNS Servers', function() {
320
329
const res = await rootResolver . resolveTxt ( name ) ;
321
330
assert . strictEqual ( res [ 0 ] [ 0 ] , string ) ;
322
331
} ) ;
332
+
333
+ describe ( 'Chain reorg' , function ( ) {
334
+ it ( 'should update SOA serial at safe height' , async ( ) => {
335
+ let lastSerial = node . ns . serial ( ) ;
336
+ let lastRoot = node . chain . safeEntry . treeRoot ;
337
+ for ( let i = 0 ; i < 100 ; i ++ ) {
338
+ // Update the Urkel tree in every block
339
+ await miner . mempool . addTX ( ( await wallet . sendUpdate (
340
+ name ,
341
+ Resource . fromJSON ( {
342
+ records : [ { type : 'TXT' , txt : [ string ] } ]
343
+ } )
344
+ ) ) . toTX ( ) ) ;
345
+ await mineBlocks ( 1 ) ;
346
+
347
+ const newSerial = node . ns . serial ( ) ;
348
+ const newRoot = node . chain . safeEntry . treeRoot ;
349
+
350
+ if ( node . chain . height % treeInterval === safeRoot ) {
351
+ assert . notEqual ( newSerial , lastSerial ) ;
352
+ assert . notBufferEqual ( newRoot , lastRoot ) ;
353
+ lastSerial = newSerial ;
354
+ lastRoot = newRoot ;
355
+ } else {
356
+ assert . strictEqual ( newSerial , lastSerial ) ;
357
+ assert . bufferEqual ( newRoot , lastRoot ) ;
358
+ }
359
+ }
360
+ } ) ;
361
+
362
+ it ( 'should survive a shallow reorg' , async ( ) => {
363
+ const lastSerial = node . ns . serial ( ) ;
364
+
365
+ // Fork point is within safe root limit
366
+ const height = miner . chain . height - ( safeRoot - 1 ) ;
367
+ const fork = await miner . chain . getEntryByHeight ( height ) ;
368
+
369
+ // Reorg
370
+ const waiter = new Promise ( ( resolve ) => {
371
+ node . chain . once ( 'reorganize' , ( tip , comp , fork ) => {
372
+ resolve ( tip , comp , fork ) ;
373
+ } ) ;
374
+ } ) ;
375
+ // Guarantee all-new timestamps
376
+ miner . network . time . offset += 6000 ;
377
+
378
+ await mineBlocks ( safeRoot , fork ) ;
379
+ await waiter ;
380
+
381
+ const newSerial = node . ns . serial ( ) ;
382
+ assert . strictEqual ( lastSerial , newSerial ) ;
383
+ } ) ;
384
+
385
+ it ( 'should not survive a deep reorg' , async ( ) => {
386
+ const lastSerial = node . ns . serial ( ) ;
387
+
388
+ // Fork point exceeds safe root limit
389
+ const height = miner . chain . height - safeRoot ;
390
+ const fork = await miner . chain . getEntryByHeight ( height ) ;
391
+
392
+ // Reorg
393
+ const waiter = new Promise ( ( resolve ) => {
394
+ node . chain . once ( 'reorganize' , ( tip , comp , fork ) => {
395
+ resolve ( tip , comp , fork ) ;
396
+ } ) ;
397
+ } ) ;
398
+ // Guarantee all-new timestamps
399
+ miner . network . time . offset += 6000 ;
400
+
401
+ await mineBlocks ( safeRoot + 1 , fork ) ;
402
+ await waiter ;
403
+
404
+ const newSerial = node . ns . serial ( ) ;
405
+ assert . notStrictEqual ( lastSerial , newSerial ) ;
406
+ } ) ;
407
+ } ) ;
323
408
} ) ;
324
409
} ) ;
325
410
}
0 commit comments