blockchain_repair_test.go 62 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977
  1. // Copyright 2020 The go-ethereum Authors
  2. // This file is part of the go-ethereum library.
  3. //
  4. // The go-ethereum library is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // The go-ethereum library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public License
  15. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
  16. // Tests that abnormal program termination (i.e.crash) and restart doesn't leave
  17. // the database in some strange state with gaps in the chain, nor with block data
  18. // dangling in the future.
  19. package core
  20. import (
  21. "math/big"
  22. "testing"
  23. "time"
  24. "github.com/ethereum/go-ethereum/common"
  25. "github.com/ethereum/go-ethereum/consensus/ethash"
  26. "github.com/ethereum/go-ethereum/core/rawdb"
  27. "github.com/ethereum/go-ethereum/core/types"
  28. "github.com/ethereum/go-ethereum/core/vm"
  29. "github.com/ethereum/go-ethereum/params"
  30. )
  31. // Tests a recovery for a short canonical chain where a recent block was already
  32. // committed to disk and then the process crashed. In this case we expect the full
  33. // chain to be rolled back to the committed block, but the chain data itself left
  34. // in the database for replaying.
  35. func TestShortRepair(t *testing.T) { testShortRepair(t, false) }
  36. func TestShortRepairWithSnapshots(t *testing.T) { testShortRepair(t, true) }
  37. func testShortRepair(t *testing.T, snapshots bool) {
  38. // Chain:
  39. // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD)
  40. //
  41. // Frozen: none
  42. // Commit: G, C4
  43. // Pivot : none
  44. //
  45. // CRASH
  46. //
  47. // ------------------------------
  48. //
  49. // Expected in leveldb:
  50. // G->C1->C2->C3->C4->C5->C6->C7->C8
  51. //
  52. // Expected head header : C8
  53. // Expected head fast block: C8
  54. // Expected head block : C4
  55. testRepair(t, &rewindTest{
  56. canonicalBlocks: 8,
  57. sidechainBlocks: 0,
  58. freezeThreshold: 16,
  59. commitBlock: 4,
  60. pivotBlock: nil,
  61. expCanonicalBlocks: 8,
  62. expSidechainBlocks: 0,
  63. expFrozen: 0,
  64. expHeadHeader: 8,
  65. expHeadFastBlock: 8,
  66. expHeadBlock: 4,
  67. }, snapshots)
  68. }
  69. // Tests a recovery for a short canonical chain where the fast sync pivot point was
  70. // already committed, after which the process crashed. In this case we expect the full
  71. // chain to be rolled back to the committed block, but the chain data itself left in
  72. // the database for replaying.
  73. func TestShortSnapSyncedRepair(t *testing.T) { testShortSnapSyncedRepair(t, false) }
  74. func TestShortSnapSyncedRepairWithSnapshots(t *testing.T) { testShortSnapSyncedRepair(t, true) }
  75. func testShortSnapSyncedRepair(t *testing.T, snapshots bool) {
  76. // Chain:
  77. // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD)
  78. //
  79. // Frozen: none
  80. // Commit: G, C4
  81. // Pivot : C4
  82. //
  83. // CRASH
  84. //
  85. // ------------------------------
  86. //
  87. // Expected in leveldb:
  88. // G->C1->C2->C3->C4->C5->C6->C7->C8
  89. //
  90. // Expected head header : C8
  91. // Expected head fast block: C8
  92. // Expected head block : C4
  93. testRepair(t, &rewindTest{
  94. canonicalBlocks: 8,
  95. sidechainBlocks: 0,
  96. freezeThreshold: 16,
  97. commitBlock: 4,
  98. pivotBlock: uint64ptr(4),
  99. expCanonicalBlocks: 8,
  100. expSidechainBlocks: 0,
  101. expFrozen: 0,
  102. expHeadHeader: 8,
  103. expHeadFastBlock: 8,
  104. expHeadBlock: 4,
  105. }, snapshots)
  106. }
  107. // Tests a recovery for a short canonical chain where the fast sync pivot point was
  108. // not yet committed, but the process crashed. In this case we expect the chain to
  109. // detect that it was fast syncing and not delete anything, since we can just pick
  110. // up directly where we left off.
  111. func TestShortSnapSyncingRepair(t *testing.T) { testShortSnapSyncingRepair(t, false) }
  112. func TestShortSnapSyncingRepairWithSnapshots(t *testing.T) { testShortSnapSyncingRepair(t, true) }
  113. func testShortSnapSyncingRepair(t *testing.T, snapshots bool) {
  114. // Chain:
  115. // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD)
  116. //
  117. // Frozen: none
  118. // Commit: G
  119. // Pivot : C4
  120. //
  121. // CRASH
  122. //
  123. // ------------------------------
  124. //
  125. // Expected in leveldb:
  126. // G->C1->C2->C3->C4->C5->C6->C7->C8
  127. //
  128. // Expected head header : C8
  129. // Expected head fast block: C8
  130. // Expected head block : G
  131. testRepair(t, &rewindTest{
  132. canonicalBlocks: 8,
  133. sidechainBlocks: 0,
  134. freezeThreshold: 16,
  135. commitBlock: 0,
  136. pivotBlock: uint64ptr(4),
  137. expCanonicalBlocks: 8,
  138. expSidechainBlocks: 0,
  139. expFrozen: 0,
  140. expHeadHeader: 8,
  141. expHeadFastBlock: 8,
  142. expHeadBlock: 0,
  143. }, snapshots)
  144. }
  145. // Tests a recovery for a short canonical chain and a shorter side chain, where a
  146. // recent block was already committed to disk and then the process crashed. In this
  147. // test scenario the side chain is below the committed block. In this case we expect
  148. // the canonical chain to be rolled back to the committed block, but the chain data
  149. // itself left in the database for replaying.
  150. func TestShortOldForkedRepair(t *testing.T) { testShortOldForkedRepair(t, false) }
  151. func TestShortOldForkedRepairWithSnapshots(t *testing.T) { testShortOldForkedRepair(t, true) }
  152. func testShortOldForkedRepair(t *testing.T, snapshots bool) {
  153. // Chain:
  154. // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD)
  155. // └->S1->S2->S3
  156. //
  157. // Frozen: none
  158. // Commit: G, C4
  159. // Pivot : none
  160. //
  161. // CRASH
  162. //
  163. // ------------------------------
  164. //
  165. // Expected in leveldb:
  166. // G->C1->C2->C3->C4->C5->C6->C7->C8
  167. // └->S1->S2->S3
  168. //
  169. // Expected head header : C8
  170. // Expected head fast block: C8
  171. // Expected head block : C4
  172. testRepair(t, &rewindTest{
  173. canonicalBlocks: 8,
  174. sidechainBlocks: 3,
  175. freezeThreshold: 16,
  176. commitBlock: 4,
  177. pivotBlock: nil,
  178. expCanonicalBlocks: 8,
  179. expSidechainBlocks: 3,
  180. expFrozen: 0,
  181. expHeadHeader: 8,
  182. expHeadFastBlock: 8,
  183. expHeadBlock: 4,
  184. }, snapshots)
  185. }
  186. // Tests a recovery for a short canonical chain and a shorter side chain, where
  187. // the fast sync pivot point was already committed to disk and then the process
  188. // crashed. In this test scenario the side chain is below the committed block. In
  189. // this case we expect the canonical chain to be rolled back to the committed block,
  190. // but the chain data itself left in the database for replaying.
  191. func TestShortOldForkedSnapSyncedRepair(t *testing.T) {
  192. testShortOldForkedSnapSyncedRepair(t, false)
  193. }
  194. func TestShortOldForkedSnapSyncedRepairWithSnapshots(t *testing.T) {
  195. testShortOldForkedSnapSyncedRepair(t, true)
  196. }
  197. func testShortOldForkedSnapSyncedRepair(t *testing.T, snapshots bool) {
  198. // Chain:
  199. // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD)
  200. // └->S1->S2->S3
  201. //
  202. // Frozen: none
  203. // Commit: G, C4
  204. // Pivot : C4
  205. //
  206. // CRASH
  207. //
  208. // ------------------------------
  209. //
  210. // Expected in leveldb:
  211. // G->C1->C2->C3->C4->C5->C6->C7->C8
  212. // └->S1->S2->S3
  213. //
  214. // Expected head header : C8
  215. // Expected head fast block: C8
  216. // Expected head block : C4
  217. testRepair(t, &rewindTest{
  218. canonicalBlocks: 8,
  219. sidechainBlocks: 3,
  220. freezeThreshold: 16,
  221. commitBlock: 4,
  222. pivotBlock: uint64ptr(4),
  223. expCanonicalBlocks: 8,
  224. expSidechainBlocks: 3,
  225. expFrozen: 0,
  226. expHeadHeader: 8,
  227. expHeadFastBlock: 8,
  228. expHeadBlock: 4,
  229. }, snapshots)
  230. }
  231. // Tests a recovery for a short canonical chain and a shorter side chain, where
  232. // the fast sync pivot point was not yet committed, but the process crashed. In this
  233. // test scenario the side chain is below the committed block. In this case we expect
  234. // the chain to detect that it was fast syncing and not delete anything, since we
  235. // can just pick up directly where we left off.
  236. func TestShortOldForkedSnapSyncingRepair(t *testing.T) {
  237. testShortOldForkedSnapSyncingRepair(t, false)
  238. }
  239. func TestShortOldForkedSnapSyncingRepairWithSnapshots(t *testing.T) {
  240. testShortOldForkedSnapSyncingRepair(t, true)
  241. }
  242. func testShortOldForkedSnapSyncingRepair(t *testing.T, snapshots bool) {
  243. // Chain:
  244. // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD)
  245. // └->S1->S2->S3
  246. //
  247. // Frozen: none
  248. // Commit: G
  249. // Pivot : C4
  250. //
  251. // CRASH
  252. //
  253. // ------------------------------
  254. //
  255. // Expected in leveldb:
  256. // G->C1->C2->C3->C4->C5->C6->C7->C8
  257. // └->S1->S2->S3
  258. //
  259. // Expected head header : C8
  260. // Expected head fast block: C8
  261. // Expected head block : G
  262. testRepair(t, &rewindTest{
  263. canonicalBlocks: 8,
  264. sidechainBlocks: 3,
  265. freezeThreshold: 16,
  266. commitBlock: 0,
  267. pivotBlock: uint64ptr(4),
  268. expCanonicalBlocks: 8,
  269. expSidechainBlocks: 3,
  270. expFrozen: 0,
  271. expHeadHeader: 8,
  272. expHeadFastBlock: 8,
  273. expHeadBlock: 0,
  274. }, snapshots)
  275. }
  276. // Tests a recovery for a short canonical chain and a shorter side chain, where a
  277. // recent block was already committed to disk and then the process crashed. In this
  278. // test scenario the side chain reaches above the committed block. In this case we
  279. // expect the canonical chain to be rolled back to the committed block, but the
  280. // chain data itself left in the database for replaying.
  281. func TestShortNewlyForkedRepair(t *testing.T) { testShortNewlyForkedRepair(t, false) }
  282. func TestShortNewlyForkedRepairWithSnapshots(t *testing.T) { testShortNewlyForkedRepair(t, true) }
  283. func testShortNewlyForkedRepair(t *testing.T, snapshots bool) {
  284. // Chain:
  285. // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD)
  286. // └->S1->S2->S3->S4->S5->S6
  287. //
  288. // Frozen: none
  289. // Commit: G, C4
  290. // Pivot : none
  291. //
  292. // CRASH
  293. //
  294. // ------------------------------
  295. //
  296. // Expected in leveldb:
  297. // G->C1->C2->C3->C4->C5->C6->C7->C8
  298. // └->S1->S2->S3->S4->S5->S6
  299. //
  300. // Expected head header : C8
  301. // Expected head fast block: C8
  302. // Expected head block : C4
  303. testRepair(t, &rewindTest{
  304. canonicalBlocks: 8,
  305. sidechainBlocks: 6,
  306. freezeThreshold: 16,
  307. commitBlock: 4,
  308. pivotBlock: nil,
  309. expCanonicalBlocks: 8,
  310. expSidechainBlocks: 6,
  311. expFrozen: 0,
  312. expHeadHeader: 8,
  313. expHeadFastBlock: 8,
  314. expHeadBlock: 4,
  315. }, snapshots)
  316. }
  317. // Tests a recovery for a short canonical chain and a shorter side chain, where
  318. // the fast sync pivot point was already committed to disk and then the process
  319. // crashed. In this test scenario the side chain reaches above the committed block.
  320. // In this case we expect the canonical chain to be rolled back to the committed
  321. // block, but the chain data itself left in the database for replaying.
  322. func TestShortNewlyForkedSnapSyncedRepair(t *testing.T) {
  323. testShortNewlyForkedSnapSyncedRepair(t, false)
  324. }
  325. func TestShortNewlyForkedSnapSyncedRepairWithSnapshots(t *testing.T) {
  326. testShortNewlyForkedSnapSyncedRepair(t, true)
  327. }
  328. func testShortNewlyForkedSnapSyncedRepair(t *testing.T, snapshots bool) {
  329. // Chain:
  330. // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD)
  331. // └->S1->S2->S3->S4->S5->S6
  332. //
  333. // Frozen: none
  334. // Commit: G, C4
  335. // Pivot : C4
  336. //
  337. // CRASH
  338. //
  339. // ------------------------------
  340. //
  341. // Expected in leveldb:
  342. // G->C1->C2->C3->C4->C5->C6->C7->C8
  343. // └->S1->S2->S3->S4->S5->S6
  344. //
  345. // Expected head header : C8
  346. // Expected head fast block: C8
  347. // Expected head block : C4
  348. testRepair(t, &rewindTest{
  349. canonicalBlocks: 8,
  350. sidechainBlocks: 6,
  351. freezeThreshold: 16,
  352. commitBlock: 4,
  353. pivotBlock: uint64ptr(4),
  354. expCanonicalBlocks: 8,
  355. expSidechainBlocks: 6,
  356. expFrozen: 0,
  357. expHeadHeader: 8,
  358. expHeadFastBlock: 8,
  359. expHeadBlock: 4,
  360. }, snapshots)
  361. }
  362. // Tests a recovery for a short canonical chain and a shorter side chain, where
  363. // the fast sync pivot point was not yet committed, but the process crashed. In
  364. // this test scenario the side chain reaches above the committed block. In this
  365. // case we expect the chain to detect that it was fast syncing and not delete
  366. // anything, since we can just pick up directly where we left off.
  367. func TestShortNewlyForkedSnapSyncingRepair(t *testing.T) {
  368. testShortNewlyForkedSnapSyncingRepair(t, false)
  369. }
  370. func TestShortNewlyForkedSnapSyncingRepairWithSnapshots(t *testing.T) {
  371. testShortNewlyForkedSnapSyncingRepair(t, true)
  372. }
  373. func testShortNewlyForkedSnapSyncingRepair(t *testing.T, snapshots bool) {
  374. // Chain:
  375. // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD)
  376. // └->S1->S2->S3->S4->S5->S6
  377. //
  378. // Frozen: none
  379. // Commit: G
  380. // Pivot : C4
  381. //
  382. // CRASH
  383. //
  384. // ------------------------------
  385. //
  386. // Expected in leveldb:
  387. // G->C1->C2->C3->C4->C5->C6->C7->C8
  388. // └->S1->S2->S3->S4->S5->S6
  389. //
  390. // Expected head header : C8
  391. // Expected head fast block: C8
  392. // Expected head block : G
  393. testRepair(t, &rewindTest{
  394. canonicalBlocks: 8,
  395. sidechainBlocks: 6,
  396. freezeThreshold: 16,
  397. commitBlock: 0,
  398. pivotBlock: uint64ptr(4),
  399. expCanonicalBlocks: 8,
  400. expSidechainBlocks: 6,
  401. expFrozen: 0,
  402. expHeadHeader: 8,
  403. expHeadFastBlock: 8,
  404. expHeadBlock: 0,
  405. }, snapshots)
  406. }
  407. // Tests a recovery for a short canonical chain and a longer side chain, where a
  408. // recent block was already committed to disk and then the process crashed. In this
  409. // case we expect the canonical chain to be rolled back to the committed block, but
  410. // the chain data itself left in the database for replaying.
  411. func TestShortReorgedRepair(t *testing.T) { testShortReorgedRepair(t, false) }
  412. func TestShortReorgedRepairWithSnapshots(t *testing.T) { testShortReorgedRepair(t, true) }
  413. func testShortReorgedRepair(t *testing.T, snapshots bool) {
  414. // Chain:
  415. // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD)
  416. // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10
  417. //
  418. // Frozen: none
  419. // Commit: G, C4
  420. // Pivot : none
  421. //
  422. // CRASH
  423. //
  424. // ------------------------------
  425. //
  426. // Expected in leveldb:
  427. // G->C1->C2->C3->C4->C5->C6->C7->C8
  428. // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10
  429. //
  430. // Expected head header : C8
  431. // Expected head fast block: C8
  432. // Expected head block : C4
  433. testRepair(t, &rewindTest{
  434. canonicalBlocks: 8,
  435. sidechainBlocks: 10,
  436. freezeThreshold: 16,
  437. commitBlock: 4,
  438. pivotBlock: nil,
  439. expCanonicalBlocks: 8,
  440. expSidechainBlocks: 10,
  441. expFrozen: 0,
  442. expHeadHeader: 8,
  443. expHeadFastBlock: 8,
  444. expHeadBlock: 4,
  445. }, snapshots)
  446. }
  447. // Tests a recovery for a short canonical chain and a longer side chain, where
  448. // the fast sync pivot point was already committed to disk and then the process
  449. // crashed. In this case we expect the canonical chain to be rolled back to the
  450. // committed block, but the chain data itself left in the database for replaying.
  451. func TestShortReorgedSnapSyncedRepair(t *testing.T) {
  452. testShortReorgedSnapSyncedRepair(t, false)
  453. }
  454. func TestShortReorgedSnapSyncedRepairWithSnapshots(t *testing.T) {
  455. testShortReorgedSnapSyncedRepair(t, true)
  456. }
  457. func testShortReorgedSnapSyncedRepair(t *testing.T, snapshots bool) {
  458. // Chain:
  459. // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD)
  460. // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10
  461. //
  462. // Frozen: none
  463. // Commit: G, C4
  464. // Pivot : C4
  465. //
  466. // CRASH
  467. //
  468. // ------------------------------
  469. //
  470. // Expected in leveldb:
  471. // G->C1->C2->C3->C4->C5->C6->C7->C8
  472. // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10
  473. //
  474. // Expected head header : C8
  475. // Expected head fast block: C8
  476. // Expected head block : C4
  477. testRepair(t, &rewindTest{
  478. canonicalBlocks: 8,
  479. sidechainBlocks: 10,
  480. freezeThreshold: 16,
  481. commitBlock: 4,
  482. pivotBlock: uint64ptr(4),
  483. expCanonicalBlocks: 8,
  484. expSidechainBlocks: 10,
  485. expFrozen: 0,
  486. expHeadHeader: 8,
  487. expHeadFastBlock: 8,
  488. expHeadBlock: 4,
  489. }, snapshots)
  490. }
  491. // Tests a recovery for a short canonical chain and a longer side chain, where
  492. // the fast sync pivot point was not yet committed, but the process crashed. In
  493. // this case we expect the chain to detect that it was fast syncing and not delete
  494. // anything, since we can just pick up directly where we left off.
  495. func TestShortReorgedSnapSyncingRepair(t *testing.T) {
  496. testShortReorgedSnapSyncingRepair(t, false)
  497. }
  498. func TestShortReorgedSnapSyncingRepairWithSnapshots(t *testing.T) {
  499. testShortReorgedSnapSyncingRepair(t, true)
  500. }
  501. func testShortReorgedSnapSyncingRepair(t *testing.T, snapshots bool) {
  502. // Chain:
  503. // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD)
  504. // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10
  505. //
  506. // Frozen: none
  507. // Commit: G
  508. // Pivot : C4
  509. //
  510. // CRASH
  511. //
  512. // ------------------------------
  513. //
  514. // Expected in leveldb:
  515. // G->C1->C2->C3->C4->C5->C6->C7->C8
  516. // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10
  517. //
  518. // Expected head header : C8
  519. // Expected head fast block: C8
  520. // Expected head block : G
  521. testRepair(t, &rewindTest{
  522. canonicalBlocks: 8,
  523. sidechainBlocks: 10,
  524. freezeThreshold: 16,
  525. commitBlock: 0,
  526. pivotBlock: uint64ptr(4),
  527. expCanonicalBlocks: 8,
  528. expSidechainBlocks: 10,
  529. expFrozen: 0,
  530. expHeadHeader: 8,
  531. expHeadFastBlock: 8,
  532. expHeadBlock: 0,
  533. }, snapshots)
  534. }
  535. // Tests a recovery for a long canonical chain with frozen blocks where a recent
  536. // block - newer than the ancient limit - was already committed to disk and then
  537. // the process crashed. In this case we expect the chain to be rolled back to the
  538. // committed block, with everything afterwards kept as fast sync data.
  539. func TestLongShallowRepair(t *testing.T) { testLongShallowRepair(t, false) }
  540. func TestLongShallowRepairWithSnapshots(t *testing.T) { testLongShallowRepair(t, true) }
  541. func testLongShallowRepair(t *testing.T, snapshots bool) {
  542. // Chain:
  543. // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD)
  544. //
  545. // Frozen:
  546. // G->C1->C2
  547. //
  548. // Commit: G, C4
  549. // Pivot : none
  550. //
  551. // CRASH
  552. //
  553. // ------------------------------
  554. //
  555. // Expected in freezer:
  556. // G->C1->C2
  557. //
  558. // Expected in leveldb:
  559. // C2)->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18
  560. //
  561. // Expected head header : C18
  562. // Expected head fast block: C18
  563. // Expected head block : C4
  564. testRepair(t, &rewindTest{
  565. canonicalBlocks: 18,
  566. sidechainBlocks: 0,
  567. freezeThreshold: 16,
  568. commitBlock: 4,
  569. pivotBlock: nil,
  570. expCanonicalBlocks: 18,
  571. expSidechainBlocks: 0,
  572. expFrozen: 3,
  573. expHeadHeader: 18,
  574. expHeadFastBlock: 18,
  575. expHeadBlock: 4,
  576. }, snapshots)
  577. }
  578. // Tests a recovery for a long canonical chain with frozen blocks where a recent
  579. // block - older than the ancient limit - was already committed to disk and then
  580. // the process crashed. In this case we expect the chain to be rolled back to the
  581. // committed block, with everything afterwards deleted.
  582. func TestLongDeepRepair(t *testing.T) { testLongDeepRepair(t, false) }
  583. func TestLongDeepRepairWithSnapshots(t *testing.T) { testLongDeepRepair(t, true) }
  584. func testLongDeepRepair(t *testing.T, snapshots bool) {
  585. // Chain:
  586. // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24 (HEAD)
  587. //
  588. // Frozen:
  589. // G->C1->C2->C3->C4->C5->C6->C7->C8
  590. //
  591. // Commit: G, C4
  592. // Pivot : none
  593. //
  594. // CRASH
  595. //
  596. // ------------------------------
  597. //
  598. // Expected in freezer:
  599. // G->C1->C2->C3->C4
  600. //
  601. // Expected in leveldb: none
  602. //
  603. // Expected head header : C4
  604. // Expected head fast block: C4
  605. // Expected head block : C4
  606. testRepair(t, &rewindTest{
  607. canonicalBlocks: 24,
  608. sidechainBlocks: 0,
  609. freezeThreshold: 16,
  610. commitBlock: 4,
  611. pivotBlock: nil,
  612. expCanonicalBlocks: 4,
  613. expSidechainBlocks: 0,
  614. expFrozen: 5,
  615. expHeadHeader: 4,
  616. expHeadFastBlock: 4,
  617. expHeadBlock: 4,
  618. }, snapshots)
  619. }
  620. // Tests a recovery for a long canonical chain with frozen blocks where the fast
  621. // sync pivot point - newer than the ancient limit - was already committed, after
  622. // which the process crashed. In this case we expect the chain to be rolled back
  623. // to the committed block, with everything afterwards kept as fast sync data.
  624. func TestLongSnapSyncedShallowRepair(t *testing.T) {
  625. testLongSnapSyncedShallowRepair(t, false)
  626. }
  627. func TestLongSnapSyncedShallowRepairWithSnapshots(t *testing.T) {
  628. testLongSnapSyncedShallowRepair(t, true)
  629. }
  630. func testLongSnapSyncedShallowRepair(t *testing.T, snapshots bool) {
  631. // Chain:
  632. // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD)
  633. //
  634. // Frozen:
  635. // G->C1->C2
  636. //
  637. // Commit: G, C4
  638. // Pivot : C4
  639. //
  640. // CRASH
  641. //
  642. // ------------------------------
  643. //
  644. // Expected in freezer:
  645. // G->C1->C2
  646. //
  647. // Expected in leveldb:
  648. // C2)->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18
  649. //
  650. // Expected head header : C18
  651. // Expected head fast block: C18
  652. // Expected head block : C4
  653. testRepair(t, &rewindTest{
  654. canonicalBlocks: 18,
  655. sidechainBlocks: 0,
  656. freezeThreshold: 16,
  657. commitBlock: 4,
  658. pivotBlock: uint64ptr(4),
  659. expCanonicalBlocks: 18,
  660. expSidechainBlocks: 0,
  661. expFrozen: 3,
  662. expHeadHeader: 18,
  663. expHeadFastBlock: 18,
  664. expHeadBlock: 4,
  665. }, snapshots)
  666. }
  667. // Tests a recovery for a long canonical chain with frozen blocks where the fast
  668. // sync pivot point - older than the ancient limit - was already committed, after
  669. // which the process crashed. In this case we expect the chain to be rolled back
  670. // to the committed block, with everything afterwards deleted.
  671. func TestLongSnapSyncedDeepRepair(t *testing.T) { testLongSnapSyncedDeepRepair(t, false) }
  672. func TestLongSnapSyncedDeepRepairWithSnapshots(t *testing.T) { testLongSnapSyncedDeepRepair(t, true) }
  673. func testLongSnapSyncedDeepRepair(t *testing.T, snapshots bool) {
  674. // Chain:
  675. // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24 (HEAD)
  676. //
  677. // Frozen:
  678. // G->C1->C2->C3->C4->C5->C6->C7->C8
  679. //
  680. // Commit: G, C4
  681. // Pivot : C4
  682. //
  683. // CRASH
  684. //
  685. // ------------------------------
  686. //
  687. // Expected in freezer:
  688. // G->C1->C2->C3->C4
  689. //
  690. // Expected in leveldb: none
  691. //
  692. // Expected head header : C4
  693. // Expected head fast block: C4
  694. // Expected head block : C4
  695. testRepair(t, &rewindTest{
  696. canonicalBlocks: 24,
  697. sidechainBlocks: 0,
  698. freezeThreshold: 16,
  699. commitBlock: 4,
  700. pivotBlock: uint64ptr(4),
  701. expCanonicalBlocks: 4,
  702. expSidechainBlocks: 0,
  703. expFrozen: 5,
  704. expHeadHeader: 4,
  705. expHeadFastBlock: 4,
  706. expHeadBlock: 4,
  707. }, snapshots)
  708. }
  709. // Tests a recovery for a long canonical chain with frozen blocks where the fast
  710. // sync pivot point - older than the ancient limit - was not yet committed, but the
  711. // process crashed. In this case we expect the chain to detect that it was fast
  712. // syncing and not delete anything, since we can just pick up directly where we
  713. // left off.
  714. func TestLongSnapSyncingShallowRepair(t *testing.T) {
  715. testLongSnapSyncingShallowRepair(t, false)
  716. }
  717. func TestLongSnapSyncingShallowRepairWithSnapshots(t *testing.T) {
  718. testLongSnapSyncingShallowRepair(t, true)
  719. }
  720. func testLongSnapSyncingShallowRepair(t *testing.T, snapshots bool) {
  721. // Chain:
  722. // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD)
  723. //
  724. // Frozen:
  725. // G->C1->C2
  726. //
  727. // Commit: G
  728. // Pivot : C4
  729. //
  730. // CRASH
  731. //
  732. // ------------------------------
  733. //
  734. // Expected in freezer:
  735. // G->C1->C2
  736. //
  737. // Expected in leveldb:
  738. // C2)->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18
  739. //
  740. // Expected head header : C18
  741. // Expected head fast block: C18
  742. // Expected head block : G
  743. testRepair(t, &rewindTest{
  744. canonicalBlocks: 18,
  745. sidechainBlocks: 0,
  746. freezeThreshold: 16,
  747. commitBlock: 0,
  748. pivotBlock: uint64ptr(4),
  749. expCanonicalBlocks: 18,
  750. expSidechainBlocks: 0,
  751. expFrozen: 3,
  752. expHeadHeader: 18,
  753. expHeadFastBlock: 18,
  754. expHeadBlock: 0,
  755. }, snapshots)
  756. }
  757. // Tests a recovery for a long canonical chain with frozen blocks where the fast
  758. // sync pivot point - newer than the ancient limit - was not yet committed, but the
  759. // process crashed. In this case we expect the chain to detect that it was fast
  760. // syncing and not delete anything, since we can just pick up directly where we
  761. // left off.
  762. func TestLongSnapSyncingDeepRepair(t *testing.T) { testLongSnapSyncingDeepRepair(t, false) }
  763. func TestLongSnapSyncingDeepRepairWithSnapshots(t *testing.T) { testLongSnapSyncingDeepRepair(t, true) }
  764. func testLongSnapSyncingDeepRepair(t *testing.T, snapshots bool) {
  765. // Chain:
  766. // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24 (HEAD)
  767. //
  768. // Frozen:
  769. // G->C1->C2->C3->C4->C5->C6->C7->C8
  770. //
  771. // Commit: G
  772. // Pivot : C4
  773. //
  774. // CRASH
  775. //
  776. // ------------------------------
  777. //
  778. // Expected in freezer:
  779. // G->C1->C2->C3->C4->C5->C6->C7->C8
  780. //
  781. // Expected in leveldb:
  782. // C8)->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24
  783. //
  784. // Expected head header : C24
  785. // Expected head fast block: C24
  786. // Expected head block : G
  787. testRepair(t, &rewindTest{
  788. canonicalBlocks: 24,
  789. sidechainBlocks: 0,
  790. freezeThreshold: 16,
  791. commitBlock: 0,
  792. pivotBlock: uint64ptr(4),
  793. expCanonicalBlocks: 24,
  794. expSidechainBlocks: 0,
  795. expFrozen: 9,
  796. expHeadHeader: 24,
  797. expHeadFastBlock: 24,
  798. expHeadBlock: 0,
  799. }, snapshots)
  800. }
  801. // Tests a recovery for a long canonical chain with frozen blocks and a shorter
  802. // side chain, where a recent block - newer than the ancient limit - was already
  803. // committed to disk and then the process crashed. In this test scenario the side
  804. // chain is below the committed block. In this case we expect the chain to be
  805. // rolled back to the committed block, with everything afterwards kept as fast
  806. // sync data; the side chain completely nuked by the freezer.
  807. func TestLongOldForkedShallowRepair(t *testing.T) {
  808. testLongOldForkedShallowRepair(t, false)
  809. }
  810. func TestLongOldForkedShallowRepairWithSnapshots(t *testing.T) {
  811. testLongOldForkedShallowRepair(t, true)
  812. }
  813. func testLongOldForkedShallowRepair(t *testing.T, snapshots bool) {
  814. // Chain:
  815. // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD)
  816. // └->S1->S2->S3
  817. //
  818. // Frozen:
  819. // G->C1->C2
  820. //
  821. // Commit: G, C4
  822. // Pivot : none
  823. //
  824. // CRASH
  825. //
  826. // ------------------------------
  827. //
  828. // Expected in freezer:
  829. // G->C1->C2
  830. //
  831. // Expected in leveldb:
  832. // C2)->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18
  833. //
  834. // Expected head header : C18
  835. // Expected head fast block: C18
  836. // Expected head block : C4
  837. testRepair(t, &rewindTest{
  838. canonicalBlocks: 18,
  839. sidechainBlocks: 3,
  840. freezeThreshold: 16,
  841. commitBlock: 4,
  842. pivotBlock: nil,
  843. expCanonicalBlocks: 18,
  844. expSidechainBlocks: 0,
  845. expFrozen: 3,
  846. expHeadHeader: 18,
  847. expHeadFastBlock: 18,
  848. expHeadBlock: 4,
  849. }, snapshots)
  850. }
  851. // Tests a recovery for a long canonical chain with frozen blocks and a shorter
  852. // side chain, where a recent block - older than the ancient limit - was already
  853. // committed to disk and then the process crashed. In this test scenario the side
  854. // chain is below the committed block. In this case we expect the canonical chain
  855. // to be rolled back to the committed block, with everything afterwards deleted;
  856. // the side chain completely nuked by the freezer.
  857. func TestLongOldForkedDeepRepair(t *testing.T) { testLongOldForkedDeepRepair(t, false) }
  858. func TestLongOldForkedDeepRepairWithSnapshots(t *testing.T) { testLongOldForkedDeepRepair(t, true) }
  859. func testLongOldForkedDeepRepair(t *testing.T, snapshots bool) {
  860. // Chain:
  861. // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24 (HEAD)
  862. // └->S1->S2->S3
  863. //
  864. // Frozen:
  865. // G->C1->C2->C3->C4->C5->C6->C7->C8
  866. //
  867. // Commit: G, C4
  868. // Pivot : none
  869. //
  870. // CRASH
  871. //
  872. // ------------------------------
  873. //
  874. // Expected in freezer:
  875. // G->C1->C2->C3->C4
  876. //
  877. // Expected in leveldb: none
  878. //
  879. // Expected head header : C4
  880. // Expected head fast block: C4
  881. // Expected head block : C4
  882. testRepair(t, &rewindTest{
  883. canonicalBlocks: 24,
  884. sidechainBlocks: 3,
  885. freezeThreshold: 16,
  886. commitBlock: 4,
  887. pivotBlock: nil,
  888. expCanonicalBlocks: 4,
  889. expSidechainBlocks: 0,
  890. expFrozen: 5,
  891. expHeadHeader: 4,
  892. expHeadFastBlock: 4,
  893. expHeadBlock: 4,
  894. }, snapshots)
  895. }
  896. // Tests a recovery for a long canonical chain with frozen blocks and a shorter
  897. // side chain, where the fast sync pivot point - newer than the ancient limit -
  898. // was already committed to disk and then the process crashed. In this test scenario
  899. // the side chain is below the committed block. In this case we expect the chain
  900. // to be rolled back to the committed block, with everything afterwards kept as
  901. // fast sync data; the side chain completely nuked by the freezer.
  902. func TestLongOldForkedSnapSyncedShallowRepair(t *testing.T) {
  903. testLongOldForkedSnapSyncedShallowRepair(t, false)
  904. }
  905. func TestLongOldForkedSnapSyncedShallowRepairWithSnapshots(t *testing.T) {
  906. testLongOldForkedSnapSyncedShallowRepair(t, true)
  907. }
  908. func testLongOldForkedSnapSyncedShallowRepair(t *testing.T, snapshots bool) {
  909. // Chain:
  910. // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD)
  911. // └->S1->S2->S3
  912. //
  913. // Frozen:
  914. // G->C1->C2
  915. //
  916. // Commit: G, C4
  917. // Pivot : C4
  918. //
  919. // CRASH
  920. //
  921. // ------------------------------
  922. //
  923. // Expected in freezer:
  924. // G->C1->C2
  925. //
  926. // Expected in leveldb:
  927. // C2)->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18
  928. //
  929. // Expected head header : C18
  930. // Expected head fast block: C18
  931. // Expected head block : C4
  932. testRepair(t, &rewindTest{
  933. canonicalBlocks: 18,
  934. sidechainBlocks: 3,
  935. freezeThreshold: 16,
  936. commitBlock: 4,
  937. pivotBlock: uint64ptr(4),
  938. expCanonicalBlocks: 18,
  939. expSidechainBlocks: 0,
  940. expFrozen: 3,
  941. expHeadHeader: 18,
  942. expHeadFastBlock: 18,
  943. expHeadBlock: 4,
  944. }, snapshots)
  945. }
  946. // Tests a recovery for a long canonical chain with frozen blocks and a shorter
  947. // side chain, where the fast sync pivot point - older than the ancient limit -
  948. // was already committed to disk and then the process crashed. In this test scenario
  949. // the side chain is below the committed block. In this case we expect the canonical
  950. // chain to be rolled back to the committed block, with everything afterwards deleted;
  951. // the side chain completely nuked by the freezer.
  952. func TestLongOldForkedSnapSyncedDeepRepair(t *testing.T) {
  953. testLongOldForkedSnapSyncedDeepRepair(t, false)
  954. }
  955. func TestLongOldForkedSnapSyncedDeepRepairWithSnapshots(t *testing.T) {
  956. testLongOldForkedSnapSyncedDeepRepair(t, true)
  957. }
  958. func testLongOldForkedSnapSyncedDeepRepair(t *testing.T, snapshots bool) {
  959. // Chain:
  960. // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24 (HEAD)
  961. // └->S1->S2->S3
  962. //
  963. // Frozen:
  964. // G->C1->C2->C3->C4->C5->C6->C7->C8
  965. //
  966. // Commit: G, C4
  967. // Pivot : C4
  968. //
  969. // CRASH
  970. //
  971. // ------------------------------
  972. //
  973. // Expected in freezer:
  974. // G->C1->C2->C3->C4
  975. //
  976. // Expected in leveldb: none
  977. //
  978. // Expected head header : C4
  979. // Expected head fast block: C4
  980. // Expected head block : C4
  981. testRepair(t, &rewindTest{
  982. canonicalBlocks: 24,
  983. sidechainBlocks: 3,
  984. freezeThreshold: 16,
  985. commitBlock: 4,
  986. pivotBlock: uint64ptr(4),
  987. expCanonicalBlocks: 4,
  988. expSidechainBlocks: 0,
  989. expFrozen: 5,
  990. expHeadHeader: 4,
  991. expHeadFastBlock: 4,
  992. expHeadBlock: 4,
  993. }, snapshots)
  994. }
  995. // Tests a recovery for a long canonical chain with frozen blocks and a shorter
  996. // side chain, where the fast sync pivot point - older than the ancient limit -
  997. // was not yet committed, but the process crashed. In this test scenario the side
  998. // chain is below the committed block. In this case we expect the chain to detect
  999. // that it was fast syncing and not delete anything. The side chain is completely
  1000. // nuked by the freezer.
  1001. func TestLongOldForkedSnapSyncingShallowRepair(t *testing.T) {
  1002. testLongOldForkedSnapSyncingShallowRepair(t, false)
  1003. }
  1004. func TestLongOldForkedSnapSyncingShallowRepairWithSnapshots(t *testing.T) {
  1005. testLongOldForkedSnapSyncingShallowRepair(t, true)
  1006. }
  1007. func testLongOldForkedSnapSyncingShallowRepair(t *testing.T, snapshots bool) {
  1008. // Chain:
  1009. // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD)
  1010. // └->S1->S2->S3
  1011. //
  1012. // Frozen:
  1013. // G->C1->C2
  1014. //
  1015. // Commit: G
  1016. // Pivot : C4
  1017. //
  1018. // CRASH
  1019. //
  1020. // ------------------------------
  1021. //
  1022. // Expected in freezer:
  1023. // G->C1->C2
  1024. //
  1025. // Expected in leveldb:
  1026. // C2)->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18
  1027. //
  1028. // Expected head header : C18
  1029. // Expected head fast block: C18
  1030. // Expected head block : G
  1031. testRepair(t, &rewindTest{
  1032. canonicalBlocks: 18,
  1033. sidechainBlocks: 3,
  1034. freezeThreshold: 16,
  1035. commitBlock: 0,
  1036. pivotBlock: uint64ptr(4),
  1037. expCanonicalBlocks: 18,
  1038. expSidechainBlocks: 0,
  1039. expFrozen: 3,
  1040. expHeadHeader: 18,
  1041. expHeadFastBlock: 18,
  1042. expHeadBlock: 0,
  1043. }, snapshots)
  1044. }
  1045. // Tests a recovery for a long canonical chain with frozen blocks and a shorter
  1046. // side chain, where the fast sync pivot point - older than the ancient limit -
  1047. // was not yet committed, but the process crashed. In this test scenario the side
  1048. // chain is below the committed block. In this case we expect the chain to detect
  1049. // that it was fast syncing and not delete anything. The side chain is completely
  1050. // nuked by the freezer.
  1051. func TestLongOldForkedSnapSyncingDeepRepair(t *testing.T) {
  1052. testLongOldForkedSnapSyncingDeepRepair(t, false)
  1053. }
  1054. func TestLongOldForkedSnapSyncingDeepRepairWithSnapshots(t *testing.T) {
  1055. testLongOldForkedSnapSyncingDeepRepair(t, true)
  1056. }
  1057. func testLongOldForkedSnapSyncingDeepRepair(t *testing.T, snapshots bool) {
  1058. // Chain:
  1059. // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24 (HEAD)
  1060. // └->S1->S2->S3
  1061. //
  1062. // Frozen:
  1063. // G->C1->C2->C3->C4->C5->C6->C7->C8
  1064. //
  1065. // Commit: G
  1066. // Pivot : C4
  1067. //
  1068. // CRASH
  1069. //
  1070. // ------------------------------
  1071. //
  1072. // Expected in freezer:
  1073. // G->C1->C2->C3->C4->C5->C6->C7->C8
  1074. //
  1075. // Expected in leveldb:
  1076. // C8)->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24
  1077. //
  1078. // Expected head header : C24
  1079. // Expected head fast block: C24
  1080. // Expected head block : G
  1081. testRepair(t, &rewindTest{
  1082. canonicalBlocks: 24,
  1083. sidechainBlocks: 3,
  1084. freezeThreshold: 16,
  1085. commitBlock: 0,
  1086. pivotBlock: uint64ptr(4),
  1087. expCanonicalBlocks: 24,
  1088. expSidechainBlocks: 0,
  1089. expFrozen: 9,
  1090. expHeadHeader: 24,
  1091. expHeadFastBlock: 24,
  1092. expHeadBlock: 0,
  1093. }, snapshots)
  1094. }
  1095. // Tests a recovery for a long canonical chain with frozen blocks and a shorter
  1096. // side chain, where a recent block - newer than the ancient limit - was already
  1097. // committed to disk and then the process crashed. In this test scenario the side
  1098. // chain is above the committed block. In this case we expect the chain to be
  1099. // rolled back to the committed block, with everything afterwards kept as fast
  1100. // sync data; the side chain completely nuked by the freezer.
  1101. func TestLongNewerForkedShallowRepair(t *testing.T) {
  1102. testLongNewerForkedShallowRepair(t, false)
  1103. }
  1104. func TestLongNewerForkedShallowRepairWithSnapshots(t *testing.T) {
  1105. testLongNewerForkedShallowRepair(t, true)
  1106. }
  1107. func testLongNewerForkedShallowRepair(t *testing.T, snapshots bool) {
  1108. // Chain:
  1109. // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD)
  1110. // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10->S11->S12
  1111. //
  1112. // Frozen:
  1113. // G->C1->C2
  1114. //
  1115. // Commit: G, C4
  1116. // Pivot : none
  1117. //
  1118. // CRASH
  1119. //
  1120. // ------------------------------
  1121. //
  1122. // Expected in freezer:
  1123. // G->C1->C2
  1124. //
  1125. // Expected in leveldb:
  1126. // C2)->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18
  1127. //
  1128. // Expected head header : C18
  1129. // Expected head fast block: C18
  1130. // Expected head block : C4
  1131. testRepair(t, &rewindTest{
  1132. canonicalBlocks: 18,
  1133. sidechainBlocks: 12,
  1134. freezeThreshold: 16,
  1135. commitBlock: 4,
  1136. pivotBlock: nil,
  1137. expCanonicalBlocks: 18,
  1138. expSidechainBlocks: 0,
  1139. expFrozen: 3,
  1140. expHeadHeader: 18,
  1141. expHeadFastBlock: 18,
  1142. expHeadBlock: 4,
  1143. }, snapshots)
  1144. }
  1145. // Tests a recovery for a long canonical chain with frozen blocks and a shorter
  1146. // side chain, where a recent block - older than the ancient limit - was already
  1147. // committed to disk and then the process crashed. In this test scenario the side
  1148. // chain is above the committed block. In this case we expect the canonical chain
  1149. // to be rolled back to the committed block, with everything afterwards deleted;
  1150. // the side chain completely nuked by the freezer.
  1151. func TestLongNewerForkedDeepRepair(t *testing.T) { testLongNewerForkedDeepRepair(t, false) }
  1152. func TestLongNewerForkedDeepRepairWithSnapshots(t *testing.T) { testLongNewerForkedDeepRepair(t, true) }
  1153. func testLongNewerForkedDeepRepair(t *testing.T, snapshots bool) {
  1154. // Chain:
  1155. // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24 (HEAD)
  1156. // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10->S11->S12
  1157. //
  1158. // Frozen:
  1159. // G->C1->C2->C3->C4->C5->C6->C7->C8
  1160. //
  1161. // Commit: G, C4
  1162. // Pivot : none
  1163. //
  1164. // CRASH
  1165. //
  1166. // ------------------------------
  1167. //
  1168. // Expected in freezer:
  1169. // G->C1->C2->C3->C4
  1170. //
  1171. // Expected in leveldb: none
  1172. //
  1173. // Expected head header : C4
  1174. // Expected head fast block: C4
  1175. // Expected head block : C4
  1176. testRepair(t, &rewindTest{
  1177. canonicalBlocks: 24,
  1178. sidechainBlocks: 12,
  1179. freezeThreshold: 16,
  1180. commitBlock: 4,
  1181. pivotBlock: nil,
  1182. expCanonicalBlocks: 4,
  1183. expSidechainBlocks: 0,
  1184. expFrozen: 5,
  1185. expHeadHeader: 4,
  1186. expHeadFastBlock: 4,
  1187. expHeadBlock: 4,
  1188. }, snapshots)
  1189. }
  1190. // Tests a recovery for a long canonical chain with frozen blocks and a shorter
  1191. // side chain, where the fast sync pivot point - newer than the ancient limit -
  1192. // was already committed to disk and then the process crashed. In this test scenario
  1193. // the side chain is above the committed block. In this case we expect the chain
  1194. // to be rolled back to the committed block, with everything afterwards kept as fast
  1195. // sync data; the side chain completely nuked by the freezer.
  1196. func TestLongNewerForkedSnapSyncedShallowRepair(t *testing.T) {
  1197. testLongNewerForkedSnapSyncedShallowRepair(t, false)
  1198. }
  1199. func TestLongNewerForkedSnapSyncedShallowRepairWithSnapshots(t *testing.T) {
  1200. testLongNewerForkedSnapSyncedShallowRepair(t, true)
  1201. }
  1202. func testLongNewerForkedSnapSyncedShallowRepair(t *testing.T, snapshots bool) {
  1203. // Chain:
  1204. // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD)
  1205. // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10->S11->S12
  1206. //
  1207. // Frozen:
  1208. // G->C1->C2
  1209. //
  1210. // Commit: G, C4
  1211. // Pivot : C4
  1212. //
  1213. // CRASH
  1214. //
  1215. // ------------------------------
  1216. //
  1217. // Expected in freezer:
  1218. // G->C1->C2
  1219. //
  1220. // Expected in leveldb:
  1221. // C2)->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18
  1222. //
  1223. // Expected head header : C18
  1224. // Expected head fast block: C18
  1225. // Expected head block : C4
  1226. testRepair(t, &rewindTest{
  1227. canonicalBlocks: 18,
  1228. sidechainBlocks: 12,
  1229. freezeThreshold: 16,
  1230. commitBlock: 4,
  1231. pivotBlock: uint64ptr(4),
  1232. expCanonicalBlocks: 18,
  1233. expSidechainBlocks: 0,
  1234. expFrozen: 3,
  1235. expHeadHeader: 18,
  1236. expHeadFastBlock: 18,
  1237. expHeadBlock: 4,
  1238. }, snapshots)
  1239. }
  1240. // Tests a recovery for a long canonical chain with frozen blocks and a shorter
  1241. // side chain, where the fast sync pivot point - older than the ancient limit -
  1242. // was already committed to disk and then the process crashed. In this test scenario
  1243. // the side chain is above the committed block. In this case we expect the canonical
  1244. // chain to be rolled back to the committed block, with everything afterwards deleted;
  1245. // the side chain completely nuked by the freezer.
  1246. func TestLongNewerForkedSnapSyncedDeepRepair(t *testing.T) {
  1247. testLongNewerForkedSnapSyncedDeepRepair(t, false)
  1248. }
  1249. func TestLongNewerForkedSnapSyncedDeepRepairWithSnapshots(t *testing.T) {
  1250. testLongNewerForkedSnapSyncedDeepRepair(t, true)
  1251. }
  1252. func testLongNewerForkedSnapSyncedDeepRepair(t *testing.T, snapshots bool) {
  1253. // Chain:
  1254. // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24 (HEAD)
  1255. // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10->S11->S12
  1256. //
  1257. // Frozen:
  1258. // G->C1->C2->C3->C4->C5->C6->C7->C8
  1259. //
  1260. // Commit: G, C4
  1261. // Pivot : C4
  1262. //
  1263. // CRASH
  1264. //
  1265. // ------------------------------
  1266. //
  1267. // Expected in freezer:
  1268. // G->C1->C2->C3->C4
  1269. //
  1270. // Expected in leveldb: none
  1271. //
  1272. // Expected head header : C4
  1273. // Expected head fast block: C4
  1274. // Expected head block : C4
  1275. testRepair(t, &rewindTest{
  1276. canonicalBlocks: 24,
  1277. sidechainBlocks: 12,
  1278. freezeThreshold: 16,
  1279. commitBlock: 4,
  1280. pivotBlock: uint64ptr(4),
  1281. expCanonicalBlocks: 4,
  1282. expSidechainBlocks: 0,
  1283. expFrozen: 5,
  1284. expHeadHeader: 4,
  1285. expHeadFastBlock: 4,
  1286. expHeadBlock: 4,
  1287. }, snapshots)
  1288. }
  1289. // Tests a recovery for a long canonical chain with frozen blocks and a shorter
  1290. // side chain, where the fast sync pivot point - older than the ancient limit -
  1291. // was not yet committed, but the process crashed. In this test scenario the side
  1292. // chain is above the committed block. In this case we expect the chain to detect
  1293. // that it was fast syncing and not delete anything. The side chain is completely
  1294. // nuked by the freezer.
  1295. func TestLongNewerForkedSnapSyncingShallowRepair(t *testing.T) {
  1296. testLongNewerForkedSnapSyncingShallowRepair(t, false)
  1297. }
  1298. func TestLongNewerForkedSnapSyncingShallowRepairWithSnapshots(t *testing.T) {
  1299. testLongNewerForkedSnapSyncingShallowRepair(t, true)
  1300. }
  1301. func testLongNewerForkedSnapSyncingShallowRepair(t *testing.T, snapshots bool) {
  1302. // Chain:
  1303. // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD)
  1304. // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10->S11->S12
  1305. //
  1306. // Frozen:
  1307. // G->C1->C2
  1308. //
  1309. // Commit: G
  1310. // Pivot : C4
  1311. //
  1312. // CRASH
  1313. //
  1314. // ------------------------------
  1315. //
  1316. // Expected in freezer:
  1317. // G->C1->C2
  1318. //
  1319. // Expected in leveldb:
  1320. // C2)->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18
  1321. //
  1322. // Expected head header : C18
  1323. // Expected head fast block: C18
  1324. // Expected head block : G
  1325. testRepair(t, &rewindTest{
  1326. canonicalBlocks: 18,
  1327. sidechainBlocks: 12,
  1328. freezeThreshold: 16,
  1329. commitBlock: 0,
  1330. pivotBlock: uint64ptr(4),
  1331. expCanonicalBlocks: 18,
  1332. expSidechainBlocks: 0,
  1333. expFrozen: 3,
  1334. expHeadHeader: 18,
  1335. expHeadFastBlock: 18,
  1336. expHeadBlock: 0,
  1337. }, snapshots)
  1338. }
  1339. // Tests a recovery for a long canonical chain with frozen blocks and a shorter
  1340. // side chain, where the fast sync pivot point - older than the ancient limit -
  1341. // was not yet committed, but the process crashed. In this test scenario the side
  1342. // chain is above the committed block. In this case we expect the chain to detect
  1343. // that it was fast syncing and not delete anything. The side chain is completely
  1344. // nuked by the freezer.
  1345. func TestLongNewerForkedSnapSyncingDeepRepair(t *testing.T) {
  1346. testLongNewerForkedSnapSyncingDeepRepair(t, false)
  1347. }
  1348. func TestLongNewerForkedSnapSyncingDeepRepairWithSnapshots(t *testing.T) {
  1349. testLongNewerForkedSnapSyncingDeepRepair(t, true)
  1350. }
  1351. func testLongNewerForkedSnapSyncingDeepRepair(t *testing.T, snapshots bool) {
  1352. // Chain:
  1353. // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24 (HEAD)
  1354. // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10->S11->S12
  1355. //
  1356. // Frozen:
  1357. // G->C1->C2->C3->C4->C5->C6->C7->C8
  1358. //
  1359. // Commit: G
  1360. // Pivot : C4
  1361. //
  1362. // CRASH
  1363. //
  1364. // ------------------------------
  1365. //
  1366. // Expected in freezer:
  1367. // G->C1->C2->C3->C4->C5->C6->C7->C8
  1368. //
  1369. // Expected in leveldb:
  1370. // C8)->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24
  1371. //
  1372. // Expected head header : C24
  1373. // Expected head fast block: C24
  1374. // Expected head block : G
  1375. testRepair(t, &rewindTest{
  1376. canonicalBlocks: 24,
  1377. sidechainBlocks: 12,
  1378. freezeThreshold: 16,
  1379. commitBlock: 0,
  1380. pivotBlock: uint64ptr(4),
  1381. expCanonicalBlocks: 24,
  1382. expSidechainBlocks: 0,
  1383. expFrozen: 9,
  1384. expHeadHeader: 24,
  1385. expHeadFastBlock: 24,
  1386. expHeadBlock: 0,
  1387. }, snapshots)
  1388. }
  1389. // Tests a recovery for a long canonical chain with frozen blocks and a longer side
  1390. // chain, where a recent block - newer than the ancient limit - was already committed
  1391. // to disk and then the process crashed. In this case we expect the chain to be
  1392. // rolled back to the committed block, with everything afterwards kept as fast sync
  1393. // data. The side chain completely nuked by the freezer.
  1394. func TestLongReorgedShallowRepair(t *testing.T) { testLongReorgedShallowRepair(t, false) }
  1395. func TestLongReorgedShallowRepairWithSnapshots(t *testing.T) { testLongReorgedShallowRepair(t, true) }
  1396. func testLongReorgedShallowRepair(t *testing.T, snapshots bool) {
  1397. // Chain:
  1398. // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD)
  1399. // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10->S11->S12->S13->S14->S15->S16->S17->S18->S19->S20->S21->S22->S23->S24->S25->S26
  1400. //
  1401. // Frozen:
  1402. // G->C1->C2
  1403. //
  1404. // Commit: G, C4
  1405. // Pivot : none
  1406. //
  1407. // CRASH
  1408. //
  1409. // ------------------------------
  1410. //
  1411. // Expected in freezer:
  1412. // G->C1->C2
  1413. //
  1414. // Expected in leveldb:
  1415. // C2)->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18
  1416. //
  1417. // Expected head header : C18
  1418. // Expected head fast block: C18
  1419. // Expected head block : C4
  1420. testRepair(t, &rewindTest{
  1421. canonicalBlocks: 18,
  1422. sidechainBlocks: 26,
  1423. freezeThreshold: 16,
  1424. commitBlock: 4,
  1425. pivotBlock: nil,
  1426. expCanonicalBlocks: 18,
  1427. expSidechainBlocks: 0,
  1428. expFrozen: 3,
  1429. expHeadHeader: 18,
  1430. expHeadFastBlock: 18,
  1431. expHeadBlock: 4,
  1432. }, snapshots)
  1433. }
  1434. // Tests a recovery for a long canonical chain with frozen blocks and a longer side
  1435. // chain, where a recent block - older than the ancient limit - was already committed
  1436. // to disk and then the process crashed. In this case we expect the canonical chains
  1437. // to be rolled back to the committed block, with everything afterwards deleted. The
  1438. // side chain completely nuked by the freezer.
  1439. func TestLongReorgedDeepRepair(t *testing.T) { testLongReorgedDeepRepair(t, false) }
  1440. func TestLongReorgedDeepRepairWithSnapshots(t *testing.T) { testLongReorgedDeepRepair(t, true) }
  1441. func testLongReorgedDeepRepair(t *testing.T, snapshots bool) {
  1442. // Chain:
  1443. // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24 (HEAD)
  1444. // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10->S11->S12->S13->S14->S15->S16->S17->S18->S19->S20->S21->S22->S23->S24->S25->S26
  1445. //
  1446. // Frozen:
  1447. // G->C1->C2->C3->C4->C5->C6->C7->C8
  1448. //
  1449. // Commit: G, C4
  1450. // Pivot : none
  1451. //
  1452. // CRASH
  1453. //
  1454. // ------------------------------
  1455. //
  1456. // Expected in freezer:
  1457. // G->C1->C2->C3->C4
  1458. //
  1459. // Expected in leveldb: none
  1460. //
  1461. // Expected head header : C4
  1462. // Expected head fast block: C4
  1463. // Expected head block : C4
  1464. testRepair(t, &rewindTest{
  1465. canonicalBlocks: 24,
  1466. sidechainBlocks: 26,
  1467. freezeThreshold: 16,
  1468. commitBlock: 4,
  1469. pivotBlock: nil,
  1470. expCanonicalBlocks: 4,
  1471. expSidechainBlocks: 0,
  1472. expFrozen: 5,
  1473. expHeadHeader: 4,
  1474. expHeadFastBlock: 4,
  1475. expHeadBlock: 4,
  1476. }, snapshots)
  1477. }
  1478. // Tests a recovery for a long canonical chain with frozen blocks and a longer
  1479. // side chain, where the fast sync pivot point - newer than the ancient limit -
  1480. // was already committed to disk and then the process crashed. In this case we
  1481. // expect the chain to be rolled back to the committed block, with everything
  1482. // afterwards kept as fast sync data. The side chain completely nuked by the
  1483. // freezer.
  1484. func TestLongReorgedSnapSyncedShallowRepair(t *testing.T) {
  1485. testLongReorgedSnapSyncedShallowRepair(t, false)
  1486. }
  1487. func TestLongReorgedSnapSyncedShallowRepairWithSnapshots(t *testing.T) {
  1488. testLongReorgedSnapSyncedShallowRepair(t, true)
  1489. }
  1490. func testLongReorgedSnapSyncedShallowRepair(t *testing.T, snapshots bool) {
  1491. // Chain:
  1492. // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD)
  1493. // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10->S11->S12->S13->S14->S15->S16->S17->S18->S19->S20->S21->S22->S23->S24->S25->S26
  1494. //
  1495. // Frozen:
  1496. // G->C1->C2
  1497. //
  1498. // Commit: G, C4
  1499. // Pivot : C4
  1500. //
  1501. // CRASH
  1502. //
  1503. // ------------------------------
  1504. //
  1505. // Expected in freezer:
  1506. // G->C1->C2
  1507. //
  1508. // Expected in leveldb:
  1509. // C2)->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18
  1510. //
  1511. // Expected head header : C18
  1512. // Expected head fast block: C18
  1513. // Expected head block : C4
  1514. testRepair(t, &rewindTest{
  1515. canonicalBlocks: 18,
  1516. sidechainBlocks: 26,
  1517. freezeThreshold: 16,
  1518. commitBlock: 4,
  1519. pivotBlock: uint64ptr(4),
  1520. expCanonicalBlocks: 18,
  1521. expSidechainBlocks: 0,
  1522. expFrozen: 3,
  1523. expHeadHeader: 18,
  1524. expHeadFastBlock: 18,
  1525. expHeadBlock: 4,
  1526. }, snapshots)
  1527. }
  1528. // Tests a recovery for a long canonical chain with frozen blocks and a longer
  1529. // side chain, where the fast sync pivot point - older than the ancient limit -
  1530. // was already committed to disk and then the process crashed. In this case we
  1531. // expect the canonical chains to be rolled back to the committed block, with
  1532. // everything afterwards deleted. The side chain completely nuked by the freezer.
  1533. func TestLongReorgedSnapSyncedDeepRepair(t *testing.T) {
  1534. testLongReorgedSnapSyncedDeepRepair(t, false)
  1535. }
  1536. func TestLongReorgedSnapSyncedDeepRepairWithSnapshots(t *testing.T) {
  1537. testLongReorgedSnapSyncedDeepRepair(t, true)
  1538. }
  1539. func testLongReorgedSnapSyncedDeepRepair(t *testing.T, snapshots bool) {
  1540. // Chain:
  1541. // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24 (HEAD)
  1542. // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10->S11->S12->S13->S14->S15->S16->S17->S18->S19->S20->S21->S22->S23->S24->S25->S26
  1543. //
  1544. // Frozen:
  1545. // G->C1->C2->C3->C4->C5->C6->C7->C8
  1546. //
  1547. // Commit: G, C4
  1548. // Pivot : C4
  1549. //
  1550. // CRASH
  1551. //
  1552. // ------------------------------
  1553. //
  1554. // Expected in freezer:
  1555. // G->C1->C2->C3->C4
  1556. //
  1557. // Expected in leveldb: none
  1558. //
  1559. // Expected head header : C4
  1560. // Expected head fast block: C4
  1561. // Expected head block : C4
  1562. testRepair(t, &rewindTest{
  1563. canonicalBlocks: 24,
  1564. sidechainBlocks: 26,
  1565. freezeThreshold: 16,
  1566. commitBlock: 4,
  1567. pivotBlock: uint64ptr(4),
  1568. expCanonicalBlocks: 4,
  1569. expSidechainBlocks: 0,
  1570. expFrozen: 5,
  1571. expHeadHeader: 4,
  1572. expHeadFastBlock: 4,
  1573. expHeadBlock: 4,
  1574. }, snapshots)
  1575. }
  1576. // Tests a recovery for a long canonical chain with frozen blocks and a longer
  1577. // side chain, where the fast sync pivot point - newer than the ancient limit -
  1578. // was not yet committed, but the process crashed. In this case we expect the
  1579. // chain to detect that it was fast syncing and not delete anything, since we
  1580. // can just pick up directly where we left off.
  1581. func TestLongReorgedSnapSyncingShallowRepair(t *testing.T) {
  1582. testLongReorgedSnapSyncingShallowRepair(t, false)
  1583. }
  1584. func TestLongReorgedSnapSyncingShallowRepairWithSnapshots(t *testing.T) {
  1585. testLongReorgedSnapSyncingShallowRepair(t, true)
  1586. }
  1587. func testLongReorgedSnapSyncingShallowRepair(t *testing.T, snapshots bool) {
  1588. // Chain:
  1589. // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD)
  1590. // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10->S11->S12->S13->S14->S15->S16->S17->S18->S19->S20->S21->S22->S23->S24->S25->S26
  1591. //
  1592. // Frozen:
  1593. // G->C1->C2
  1594. //
  1595. // Commit: G
  1596. // Pivot : C4
  1597. //
  1598. // CRASH
  1599. //
  1600. // ------------------------------
  1601. //
  1602. // Expected in freezer:
  1603. // G->C1->C2
  1604. //
  1605. // Expected in leveldb:
  1606. // C2)->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18
  1607. //
  1608. // Expected head header : C18
  1609. // Expected head fast block: C18
  1610. // Expected head block : G
  1611. testRepair(t, &rewindTest{
  1612. canonicalBlocks: 18,
  1613. sidechainBlocks: 26,
  1614. freezeThreshold: 16,
  1615. commitBlock: 0,
  1616. pivotBlock: uint64ptr(4),
  1617. expCanonicalBlocks: 18,
  1618. expSidechainBlocks: 0,
  1619. expFrozen: 3,
  1620. expHeadHeader: 18,
  1621. expHeadFastBlock: 18,
  1622. expHeadBlock: 0,
  1623. }, snapshots)
  1624. }
  1625. // Tests a recovery for a long canonical chain with frozen blocks and a longer
  1626. // side chain, where the fast sync pivot point - older than the ancient limit -
  1627. // was not yet committed, but the process crashed. In this case we expect the
  1628. // chain to detect that it was fast syncing and not delete anything, since we
  1629. // can just pick up directly where we left off.
  1630. func TestLongReorgedSnapSyncingDeepRepair(t *testing.T) {
  1631. testLongReorgedSnapSyncingDeepRepair(t, false)
  1632. }
  1633. func TestLongReorgedSnapSyncingDeepRepairWithSnapshots(t *testing.T) {
  1634. testLongReorgedSnapSyncingDeepRepair(t, true)
  1635. }
  1636. func testLongReorgedSnapSyncingDeepRepair(t *testing.T, snapshots bool) {
  1637. // Chain:
  1638. // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24 (HEAD)
  1639. // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10->S11->S12->S13->S14->S15->S16->S17->S18->S19->S20->S21->S22->S23->S24->S25->S26
  1640. //
  1641. // Frozen:
  1642. // G->C1->C2->C3->C4->C5->C6->C7->C8
  1643. //
  1644. // Commit: G
  1645. // Pivot : C4
  1646. //
  1647. // CRASH
  1648. //
  1649. // ------------------------------
  1650. //
  1651. // Expected in freezer:
  1652. // G->C1->C2->C3->C4->C5->C6->C7->C8
  1653. //
  1654. // Expected in leveldb:
  1655. // C8)->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24
  1656. //
  1657. // Expected head header : C24
  1658. // Expected head fast block: C24
  1659. // Expected head block : G
  1660. testRepair(t, &rewindTest{
  1661. canonicalBlocks: 24,
  1662. sidechainBlocks: 26,
  1663. freezeThreshold: 16,
  1664. commitBlock: 0,
  1665. pivotBlock: uint64ptr(4),
  1666. expCanonicalBlocks: 24,
  1667. expSidechainBlocks: 0,
  1668. expFrozen: 9,
  1669. expHeadHeader: 24,
  1670. expHeadFastBlock: 24,
  1671. expHeadBlock: 0,
  1672. }, snapshots)
  1673. }
  1674. func testRepair(t *testing.T, tt *rewindTest, snapshots bool) {
  1675. // It's hard to follow the test case, visualize the input
  1676. //log.Root().SetHandler(log.LvlFilterHandler(log.LvlTrace, log.StreamHandler(os.Stderr, log.TerminalFormat(true))))
  1677. // fmt.Println(tt.dump(true))
  1678. // Create a temporary persistent database
  1679. datadir := t.TempDir()
  1680. db, err := rawdb.NewLevelDBDatabaseWithFreezer(datadir, 0, 0, datadir, "", false)
  1681. if err != nil {
  1682. t.Fatalf("Failed to create persistent database: %v", err)
  1683. }
  1684. defer db.Close() // Might double close, should be fine
  1685. // Initialize a fresh chain
  1686. var (
  1687. genesis = (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
  1688. engine = ethash.NewFullFaker()
  1689. config = &CacheConfig{
  1690. TrieCleanLimit: 256,
  1691. TrieDirtyLimit: 256,
  1692. TrieTimeLimit: 5 * time.Minute,
  1693. SnapshotLimit: 0, // Disable snapshot by default
  1694. }
  1695. )
  1696. defer engine.Close()
  1697. if snapshots {
  1698. config.SnapshotLimit = 256
  1699. config.SnapshotWait = true
  1700. }
  1701. chain, err := NewBlockChain(db, config, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil)
  1702. if err != nil {
  1703. t.Fatalf("Failed to create chain: %v", err)
  1704. }
  1705. // If sidechain blocks are needed, make a light chain and import it
  1706. var sideblocks types.Blocks
  1707. if tt.sidechainBlocks > 0 {
  1708. sideblocks, _ = GenerateChain(params.TestChainConfig, genesis, engine, rawdb.NewMemoryDatabase(), tt.sidechainBlocks, func(i int, b *BlockGen) {
  1709. b.SetCoinbase(common.Address{0x01})
  1710. })
  1711. if _, err := chain.InsertChain(sideblocks); err != nil {
  1712. t.Fatalf("Failed to import side chain: %v", err)
  1713. }
  1714. }
  1715. canonblocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, rawdb.NewMemoryDatabase(), tt.canonicalBlocks, func(i int, b *BlockGen) {
  1716. b.SetCoinbase(common.Address{0x02})
  1717. b.SetDifficulty(big.NewInt(1000000))
  1718. })
  1719. if _, err := chain.InsertChain(canonblocks[:tt.commitBlock]); err != nil {
  1720. t.Fatalf("Failed to import canonical chain start: %v", err)
  1721. }
  1722. if tt.commitBlock > 0 {
  1723. chain.stateCache.TrieDB().Commit(canonblocks[tt.commitBlock-1].Root(), true, nil)
  1724. if snapshots {
  1725. if err := chain.snaps.Cap(canonblocks[tt.commitBlock-1].Root(), 0); err != nil {
  1726. t.Fatalf("Failed to flatten snapshots: %v", err)
  1727. }
  1728. }
  1729. }
  1730. if _, err := chain.InsertChain(canonblocks[tt.commitBlock:]); err != nil {
  1731. t.Fatalf("Failed to import canonical chain tail: %v", err)
  1732. }
  1733. // Force run a freeze cycle
  1734. type freezer interface {
  1735. Freeze(threshold uint64) error
  1736. Ancients() (uint64, error)
  1737. }
  1738. db.(freezer).Freeze(tt.freezeThreshold)
  1739. // Set the simulated pivot block
  1740. if tt.pivotBlock != nil {
  1741. rawdb.WriteLastPivotNumber(db, *tt.pivotBlock)
  1742. }
  1743. // Pull the plug on the database, simulating a hard crash
  1744. db.Close()
  1745. // Start a new blockchain back up and see where the repair leads us
  1746. db, err = rawdb.NewLevelDBDatabaseWithFreezer(datadir, 0, 0, datadir, "", false)
  1747. if err != nil {
  1748. t.Fatalf("Failed to reopen persistent database: %v", err)
  1749. }
  1750. defer db.Close()
  1751. newChain, err := NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil)
  1752. if err != nil {
  1753. t.Fatalf("Failed to recreate chain: %v", err)
  1754. }
  1755. defer newChain.Stop()
  1756. // Iterate over all the remaining blocks and ensure there are no gaps
  1757. verifyNoGaps(t, newChain, true, canonblocks)
  1758. verifyNoGaps(t, newChain, false, sideblocks)
  1759. verifyCutoff(t, newChain, true, canonblocks, tt.expCanonicalBlocks)
  1760. verifyCutoff(t, newChain, false, sideblocks, tt.expSidechainBlocks)
  1761. if head := newChain.CurrentHeader(); head.Number.Uint64() != tt.expHeadHeader {
  1762. t.Errorf("Head header mismatch: have %d, want %d", head.Number, tt.expHeadHeader)
  1763. }
  1764. if head := newChain.CurrentFastBlock(); head.NumberU64() != tt.expHeadFastBlock {
  1765. t.Errorf("Head fast block mismatch: have %d, want %d", head.NumberU64(), tt.expHeadFastBlock)
  1766. }
  1767. if head := newChain.CurrentBlock(); head.NumberU64() != tt.expHeadBlock {
  1768. t.Errorf("Head block mismatch: have %d, want %d", head.NumberU64(), tt.expHeadBlock)
  1769. }
  1770. if frozen, err := db.(freezer).Ancients(); err != nil {
  1771. t.Errorf("Failed to retrieve ancient count: %v\n", err)
  1772. } else if int(frozen) != tt.expFrozen {
  1773. t.Errorf("Frozen block count mismatch: have %d, want %d", frozen, tt.expFrozen)
  1774. }
  1775. }
  1776. // TestIssue23496 tests scenario described in https://github.com/ethereum/go-ethereum/pull/23496#issuecomment-926393893
  1777. // Credits to @zzyalbert for finding the issue.
  1778. //
  1779. // Local chain owns these blocks:
  1780. // G B1 B2 B3 B4
  1781. // B1: state committed
  1782. // B2: snapshot disk layer
  1783. // B3: state committed
  1784. // B4: head block
  1785. //
  1786. // Crash happens without fully persisting snapshot and in-memory states,
  1787. // chain rewinds itself to the B1 (skip B3 in order to recover snapshot)
  1788. // In this case the snapshot layer of B3 is not created because of existent
  1789. // state.
  1790. func TestIssue23496(t *testing.T) {
  1791. // It's hard to follow the test case, visualize the input
  1792. //log.Root().SetHandler(log.LvlFilterHandler(log.LvlTrace, log.StreamHandler(os.Stderr, log.TerminalFormat(true))))
  1793. // Create a temporary persistent database
  1794. datadir := t.TempDir()
  1795. db, err := rawdb.NewLevelDBDatabaseWithFreezer(datadir, 0, 0, datadir, "", false)
  1796. if err != nil {
  1797. t.Fatalf("Failed to create persistent database: %v", err)
  1798. }
  1799. defer db.Close() // Might double close, should be fine
  1800. // Initialize a fresh chain
  1801. var (
  1802. genesis = (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
  1803. engine = ethash.NewFullFaker()
  1804. config = &CacheConfig{
  1805. TrieCleanLimit: 256,
  1806. TrieDirtyLimit: 256,
  1807. TrieTimeLimit: 5 * time.Minute,
  1808. SnapshotLimit: 256,
  1809. SnapshotWait: true,
  1810. }
  1811. )
  1812. chain, err := NewBlockChain(db, config, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil)
  1813. if err != nil {
  1814. t.Fatalf("Failed to create chain: %v", err)
  1815. }
  1816. blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, rawdb.NewMemoryDatabase(), 4, func(i int, b *BlockGen) {
  1817. b.SetCoinbase(common.Address{0x02})
  1818. b.SetDifficulty(big.NewInt(1000000))
  1819. })
  1820. // Insert block B1 and commit the state into disk
  1821. if _, err := chain.InsertChain(blocks[:1]); err != nil {
  1822. t.Fatalf("Failed to import canonical chain start: %v", err)
  1823. }
  1824. chain.stateCache.TrieDB().Commit(blocks[0].Root(), true, nil)
  1825. // Insert block B2 and commit the snapshot into disk
  1826. if _, err := chain.InsertChain(blocks[1:2]); err != nil {
  1827. t.Fatalf("Failed to import canonical chain start: %v", err)
  1828. }
  1829. if err := chain.snaps.Cap(blocks[1].Root(), 0); err != nil {
  1830. t.Fatalf("Failed to flatten snapshots: %v", err)
  1831. }
  1832. // Insert block B3 and commit the state into disk
  1833. if _, err := chain.InsertChain(blocks[2:3]); err != nil {
  1834. t.Fatalf("Failed to import canonical chain start: %v", err)
  1835. }
  1836. chain.stateCache.TrieDB().Commit(blocks[2].Root(), true, nil)
  1837. // Insert the remaining blocks
  1838. if _, err := chain.InsertChain(blocks[3:]); err != nil {
  1839. t.Fatalf("Failed to import canonical chain tail: %v", err)
  1840. }
  1841. // Pull the plug on the database, simulating a hard crash
  1842. db.Close()
  1843. // Start a new blockchain back up and see where the repair leads us
  1844. db, err = rawdb.NewLevelDBDatabaseWithFreezer(datadir, 0, 0, datadir, "", false)
  1845. if err != nil {
  1846. t.Fatalf("Failed to reopen persistent database: %v", err)
  1847. }
  1848. defer db.Close()
  1849. chain, err = NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil)
  1850. if err != nil {
  1851. t.Fatalf("Failed to recreate chain: %v", err)
  1852. }
  1853. defer chain.Stop()
  1854. if head := chain.CurrentHeader(); head.Number.Uint64() != uint64(4) {
  1855. t.Errorf("Head header mismatch: have %d, want %d", head.Number, 4)
  1856. }
  1857. if head := chain.CurrentFastBlock(); head.NumberU64() != uint64(4) {
  1858. t.Errorf("Head fast block mismatch: have %d, want %d", head.NumberU64(), uint64(4))
  1859. }
  1860. if head := chain.CurrentBlock(); head.NumberU64() != uint64(1) {
  1861. t.Errorf("Head block mismatch: have %d, want %d", head.NumberU64(), uint64(1))
  1862. }
  1863. // Reinsert B2-B4
  1864. if _, err := chain.InsertChain(blocks[1:]); err != nil {
  1865. t.Fatalf("Failed to import canonical chain tail: %v", err)
  1866. }
  1867. if head := chain.CurrentHeader(); head.Number.Uint64() != uint64(4) {
  1868. t.Errorf("Head header mismatch: have %d, want %d", head.Number, 4)
  1869. }
  1870. if head := chain.CurrentFastBlock(); head.NumberU64() != uint64(4) {
  1871. t.Errorf("Head fast block mismatch: have %d, want %d", head.NumberU64(), uint64(4))
  1872. }
  1873. if head := chain.CurrentBlock(); head.NumberU64() != uint64(4) {
  1874. t.Errorf("Head block mismatch: have %d, want %d", head.NumberU64(), uint64(4))
  1875. }
  1876. if layer := chain.Snapshots().Snapshot(blocks[2].Root()); layer == nil {
  1877. t.Error("Failed to regenerate the snapshot of known state")
  1878. }
  1879. }