@@ -21,12 +21,16 @@ import (
2121 "errors"
2222 "fmt"
2323 "math/rand"
24+ "os"
25+ "path/filepath"
26+ "strconv"
2427 "testing"
2528
2629 "github.com/ethereum/go-ethereum/common"
2730 "github.com/ethereum/go-ethereum/core/rawdb"
2831 "github.com/ethereum/go-ethereum/core/types"
2932 "github.com/ethereum/go-ethereum/crypto"
33+ "github.com/ethereum/go-ethereum/ethdb"
3034 "github.com/ethereum/go-ethereum/internal/testrand"
3135 "github.com/ethereum/go-ethereum/rlp"
3236 "github.com/ethereum/go-ethereum/trie"
@@ -121,7 +125,7 @@ type tester struct {
121125 snapStorages map [common.Hash ]map [common.Hash ]map [common.Hash ][]byte // Keyed by the hash of account address and the hash of storage key
122126}
123127
124- func newTester (t * testing.T , historyLimit uint64 , isVerkle bool , layers int , enableIndex bool ) * tester {
128+ func newTester (t * testing.T , historyLimit uint64 , isVerkle bool , layers int , enableIndex bool , journalDir string ) * tester {
125129 var (
126130 disk , _ = rawdb .Open (rawdb .NewMemoryDatabase (), rawdb.OpenOptions {Ancient : t .TempDir ()})
127131 db = New (disk , & Config {
@@ -131,6 +135,7 @@ func newTester(t *testing.T, historyLimit uint64, isVerkle bool, layers int, ena
131135 StateCleanSize : 256 * 1024 ,
132136 WriteBufferSize : 256 * 1024 ,
133137 NoAsyncFlush : true ,
138+ JournalDirectory : journalDir ,
134139 }, isVerkle )
135140
136141 obj = & tester {
@@ -466,7 +471,7 @@ func TestDatabaseRollback(t *testing.T) {
466471 }()
467472
468473 // Verify state histories
469- tester := newTester (t , 0 , false , 32 , false )
474+ tester := newTester (t , 0 , false , 32 , false , "" )
470475 defer tester .release ()
471476
472477 if err := tester .verifyHistory (); err != nil {
@@ -500,7 +505,7 @@ func TestDatabaseRecoverable(t *testing.T) {
500505 }()
501506
502507 var (
503- tester = newTester (t , 0 , false , 12 , false )
508+ tester = newTester (t , 0 , false , 12 , false , "" )
504509 index = tester .bottomIndex ()
505510 )
506511 defer tester .release ()
@@ -544,7 +549,7 @@ func TestDisable(t *testing.T) {
544549 maxDiffLayers = 128
545550 }()
546551
547- tester := newTester (t , 0 , false , 32 , false )
552+ tester := newTester (t , 0 , false , 32 , false , "" )
548553 defer tester .release ()
549554
550555 stored := crypto .Keccak256Hash (rawdb .ReadAccountTrieNode (tester .db .diskdb , nil ))
@@ -586,7 +591,7 @@ func TestCommit(t *testing.T) {
586591 maxDiffLayers = 128
587592 }()
588593
589- tester := newTester (t , 0 , false , 12 , false )
594+ tester := newTester (t , 0 , false , 12 , false , "" )
590595 defer tester .release ()
591596
592597 if err := tester .db .Commit (tester .lastHash (), false ); err != nil {
@@ -610,20 +615,25 @@ func TestCommit(t *testing.T) {
610615}
611616
612617func TestJournal (t * testing.T ) {
618+ testJournal (t , "" )
619+ testJournal (t , filepath .Join (t .TempDir (), strconv .Itoa (rand .Intn (10000 ))))
620+ }
621+
622+ func testJournal (t * testing.T , journalDir string ) {
613623 // Redefine the diff layer depth allowance for faster testing.
614624 maxDiffLayers = 4
615625 defer func () {
616626 maxDiffLayers = 128
617627 }()
618628
619- tester := newTester (t , 0 , false , 12 , false )
629+ tester := newTester (t , 0 , false , 12 , false , journalDir )
620630 defer tester .release ()
621631
622632 if err := tester .db .Journal (tester .lastHash ()); err != nil {
623633 t .Errorf ("Failed to journal, err: %v" , err )
624634 }
625635 tester .db .Close ()
626- tester .db = New (tester .db .diskdb , nil , false )
636+ tester .db = New (tester .db .diskdb , tester . db . config , false )
627637
628638 // Verify states including disk layer and all diff on top.
629639 for i := 0 ; i < len (tester .roots ); i ++ {
@@ -640,13 +650,30 @@ func TestJournal(t *testing.T) {
640650}
641651
642652func TestCorruptedJournal (t * testing.T ) {
653+ testCorruptedJournal (t , "" , func (db ethdb.Database ) {
654+ // Mutate the journal in disk, it should be regarded as invalid
655+ blob := rawdb .ReadTrieJournal (db )
656+ blob [0 ] = 0xa
657+ rawdb .WriteTrieJournal (db , blob )
658+ })
659+
660+ directory := filepath .Join (t .TempDir (), strconv .Itoa (rand .Intn (10000 )))
661+ testCorruptedJournal (t , directory , func (_ ethdb.Database ) {
662+ f , _ := os .OpenFile (filepath .Join (directory , "merkle.journal" ), os .O_WRONLY , 0644 )
663+ f .WriteAt ([]byte {0xa }, 0 )
664+ f .Sync ()
665+ f .Close ()
666+ })
667+ }
668+
669+ func testCorruptedJournal (t * testing.T , journalDir string , modifyFn func (database ethdb.Database )) {
643670 // Redefine the diff layer depth allowance for faster testing.
644671 maxDiffLayers = 4
645672 defer func () {
646673 maxDiffLayers = 128
647674 }()
648675
649- tester := newTester (t , 0 , false , 12 , false )
676+ tester := newTester (t , 0 , false , 12 , false , journalDir )
650677 defer tester .release ()
651678
652679 if err := tester .db .Journal (tester .lastHash ()); err != nil {
@@ -655,13 +682,10 @@ func TestCorruptedJournal(t *testing.T) {
655682 tester .db .Close ()
656683 root := crypto .Keccak256Hash (rawdb .ReadAccountTrieNode (tester .db .diskdb , nil ))
657684
658- // Mutate the journal in disk, it should be regarded as invalid
659- blob := rawdb .ReadTrieJournal (tester .db .diskdb )
660- blob [0 ] = 0xa
661- rawdb .WriteTrieJournal (tester .db .diskdb , blob )
685+ modifyFn (tester .db .diskdb )
662686
663687 // Verify states, all not-yet-written states should be discarded
664- tester .db = New (tester .db .diskdb , nil , false )
688+ tester .db = New (tester .db .diskdb , tester . db . config , false )
665689 for i := 0 ; i < len (tester .roots ); i ++ {
666690 if tester .roots [i ] == root {
667691 if err := tester .verifyState (root ); err != nil {
@@ -694,7 +718,7 @@ func TestTailTruncateHistory(t *testing.T) {
694718 maxDiffLayers = 128
695719 }()
696720
697- tester := newTester (t , 10 , false , 12 , false )
721+ tester := newTester (t , 10 , false , 12 , false , "" )
698722 defer tester .release ()
699723
700724 tester .db .Close ()
0 commit comments