@ -35,6 +35,7 @@ import (
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie"
"github.com/ethereum/go-ethereum/trie"
"github.com/ethereum/go-ethereum/trie/triedb/pathdb"
"github.com/ethereum/go-ethereum/trie/trienode"
"github.com/ethereum/go-ethereum/trie/trienode"
"golang.org/x/crypto/sha3"
"golang.org/x/crypto/sha3"
"golang.org/x/exp/slices"
"golang.org/x/exp/slices"
@ -561,6 +562,11 @@ func noProofStorageRequestHandler(t *testPeer, requestId uint64, root common.Has
func TestSyncBloatedProof ( t * testing . T ) {
func TestSyncBloatedProof ( t * testing . T ) {
t . Parallel ( )
t . Parallel ( )
testSyncBloatedProof ( t , rawdb . HashScheme )
testSyncBloatedProof ( t , rawdb . PathScheme )
}
func testSyncBloatedProof ( t * testing . T , scheme string ) {
var (
var (
once sync . Once
once sync . Once
cancel = make ( chan struct { } )
cancel = make ( chan struct { } )
@ -570,7 +576,7 @@ func TestSyncBloatedProof(t *testing.T) {
} )
} )
}
}
)
)
nodeScheme , sourceAccountTrie , elems := makeAccountTrieNoStorage ( 100 )
nodeScheme , sourceAccountTrie , elems := makeAccountTrieNoStorage ( 100 , scheme )
source := newTestPeer ( "source" , t , term )
source := newTestPeer ( "source" , t , term )
source . accountTrie = sourceAccountTrie . Copy ( )
source . accountTrie = sourceAccountTrie . Copy ( )
source . accountValues = elems
source . accountValues = elems
@ -638,6 +644,11 @@ func setupSyncer(scheme string, peers ...*testPeer) *Syncer {
func TestSync ( t * testing . T ) {
func TestSync ( t * testing . T ) {
t . Parallel ( )
t . Parallel ( )
testSync ( t , rawdb . HashScheme )
testSync ( t , rawdb . PathScheme )
}
func testSync ( t * testing . T , scheme string ) {
var (
var (
once sync . Once
once sync . Once
cancel = make ( chan struct { } )
cancel = make ( chan struct { } )
@ -647,7 +658,7 @@ func TestSync(t *testing.T) {
} )
} )
}
}
)
)
nodeScheme , sourceAccountTrie , elems := makeAccountTrieNoStorage ( 100 )
nodeScheme , sourceAccountTrie , elems := makeAccountTrieNoStorage ( 100 , scheme )
mkSource := func ( name string ) * testPeer {
mkSource := func ( name string ) * testPeer {
source := newTestPeer ( name , t , term )
source := newTestPeer ( name , t , term )
@ -659,7 +670,7 @@ func TestSync(t *testing.T) {
if err := syncer . Sync ( sourceAccountTrie . Hash ( ) , cancel ) ; err != nil {
if err := syncer . Sync ( sourceAccountTrie . Hash ( ) , cancel ) ; err != nil {
t . Fatalf ( "sync failed: %v" , err )
t . Fatalf ( "sync failed: %v" , err )
}
}
verifyTrie ( syncer . db , sourceAccountTrie . Hash ( ) , t )
verifyTrie ( scheme , s yncer . db , sourceAccountTrie . Hash ( ) , t )
}
}
// TestSyncTinyTriePanic tests a basic sync with one peer, and a tiny trie. This caused a
// TestSyncTinyTriePanic tests a basic sync with one peer, and a tiny trie. This caused a
@ -667,6 +678,11 @@ func TestSync(t *testing.T) {
func TestSyncTinyTriePanic ( t * testing . T ) {
func TestSyncTinyTriePanic ( t * testing . T ) {
t . Parallel ( )
t . Parallel ( )
testSyncTinyTriePanic ( t , rawdb . HashScheme )
testSyncTinyTriePanic ( t , rawdb . PathScheme )
}
func testSyncTinyTriePanic ( t * testing . T , scheme string ) {
var (
var (
once sync . Once
once sync . Once
cancel = make ( chan struct { } )
cancel = make ( chan struct { } )
@ -676,7 +692,7 @@ func TestSyncTinyTriePanic(t *testing.T) {
} )
} )
}
}
)
)
nodeScheme , sourceAccountTrie , elems := makeAccountTrieNoStorage ( 1 )
nodeScheme , sourceAccountTrie , elems := makeAccountTrieNoStorage ( 1 , scheme )
mkSource := func ( name string ) * testPeer {
mkSource := func ( name string ) * testPeer {
source := newTestPeer ( name , t , term )
source := newTestPeer ( name , t , term )
@ -690,13 +706,18 @@ func TestSyncTinyTriePanic(t *testing.T) {
t . Fatalf ( "sync failed: %v" , err )
t . Fatalf ( "sync failed: %v" , err )
}
}
close ( done )
close ( done )
verifyTrie ( syncer . db , sourceAccountTrie . Hash ( ) , t )
verifyTrie ( scheme , s yncer . db , sourceAccountTrie . Hash ( ) , t )
}
}
// TestMultiSync tests a basic sync with multiple peers
// TestMultiSync tests a basic sync with multiple peers
func TestMultiSync ( t * testing . T ) {
func TestMultiSync ( t * testing . T ) {
t . Parallel ( )
t . Parallel ( )
testMultiSync ( t , rawdb . HashScheme )
testMultiSync ( t , rawdb . PathScheme )
}
func testMultiSync ( t * testing . T , scheme string ) {
var (
var (
once sync . Once
once sync . Once
cancel = make ( chan struct { } )
cancel = make ( chan struct { } )
@ -706,7 +727,7 @@ func TestMultiSync(t *testing.T) {
} )
} )
}
}
)
)
nodeScheme , sourceAccountTrie , elems := makeAccountTrieNoStorage ( 100 )
nodeScheme , sourceAccountTrie , elems := makeAccountTrieNoStorage ( 100 , scheme )
mkSource := func ( name string ) * testPeer {
mkSource := func ( name string ) * testPeer {
source := newTestPeer ( name , t , term )
source := newTestPeer ( name , t , term )
@ -720,13 +741,18 @@ func TestMultiSync(t *testing.T) {
t . Fatalf ( "sync failed: %v" , err )
t . Fatalf ( "sync failed: %v" , err )
}
}
close ( done )
close ( done )
verifyTrie ( syncer . db , sourceAccountTrie . Hash ( ) , t )
verifyTrie ( scheme , s yncer . db , sourceAccountTrie . Hash ( ) , t )
}
}
// TestSyncWithStorage tests basic sync using accounts + storage + code
// TestSyncWithStorage tests basic sync using accounts + storage + code
func TestSyncWithStorage ( t * testing . T ) {
func TestSyncWithStorage ( t * testing . T ) {
t . Parallel ( )
t . Parallel ( )
testSyncWithStorage ( t , rawdb . HashScheme )
testSyncWithStorage ( t , rawdb . PathScheme )
}
func testSyncWithStorage ( t * testing . T , scheme string ) {
var (
var (
once sync . Once
once sync . Once
cancel = make ( chan struct { } )
cancel = make ( chan struct { } )
@ -736,7 +762,7 @@ func TestSyncWithStorage(t *testing.T) {
} )
} )
}
}
)
)
nodeScheme , sourceAccountTrie , elems , storageTries , storageElems := makeAccountTrieWithStorage ( 3 , 3000 , true , false )
nodeScheme , sourceAccountTrie , elems , storageTries , storageElems := makeAccountTrieWithStorage ( scheme , 3 , 3000 , true , false )
mkSource := func ( name string ) * testPeer {
mkSource := func ( name string ) * testPeer {
source := newTestPeer ( name , t , term )
source := newTestPeer ( name , t , term )
@ -752,13 +778,18 @@ func TestSyncWithStorage(t *testing.T) {
t . Fatalf ( "sync failed: %v" , err )
t . Fatalf ( "sync failed: %v" , err )
}
}
close ( done )
close ( done )
verifyTrie ( syncer . db , sourceAccountTrie . Hash ( ) , t )
verifyTrie ( scheme , s yncer . db , sourceAccountTrie . Hash ( ) , t )
}
}
// TestMultiSyncManyUseless contains one good peer, and many which doesn't return anything valuable at all
// TestMultiSyncManyUseless contains one good peer, and many which doesn't return anything valuable at all
func TestMultiSyncManyUseless ( t * testing . T ) {
func TestMultiSyncManyUseless ( t * testing . T ) {
t . Parallel ( )
t . Parallel ( )
testMultiSyncManyUseless ( t , rawdb . HashScheme )
testMultiSyncManyUseless ( t , rawdb . PathScheme )
}
func testMultiSyncManyUseless ( t * testing . T , scheme string ) {
var (
var (
once sync . Once
once sync . Once
cancel = make ( chan struct { } )
cancel = make ( chan struct { } )
@ -768,7 +799,7 @@ func TestMultiSyncManyUseless(t *testing.T) {
} )
} )
}
}
)
)
nodeScheme , sourceAccountTrie , elems , storageTries , storageElems := makeAccountTrieWithStorage ( 100 , 3000 , true , false )
nodeScheme , sourceAccountTrie , elems , storageTries , storageElems := makeAccountTrieWithStorage ( scheme , 100 , 3000 , true , false )
mkSource := func ( name string , noAccount , noStorage , noTrieNode bool ) * testPeer {
mkSource := func ( name string , noAccount , noStorage , noTrieNode bool ) * testPeer {
source := newTestPeer ( name , t , term )
source := newTestPeer ( name , t , term )
@ -801,11 +832,18 @@ func TestMultiSyncManyUseless(t *testing.T) {
t . Fatalf ( "sync failed: %v" , err )
t . Fatalf ( "sync failed: %v" , err )
}
}
close ( done )
close ( done )
verifyTrie ( syncer . db , sourceAccountTrie . Hash ( ) , t )
verifyTrie ( scheme , s yncer . db , sourceAccountTrie . Hash ( ) , t )
}
}
// TestMultiSyncManyUseless contains one good peer, and many which doesn't return anything valuable at all
// TestMultiSyncManyUseless contains one good peer, and many which doesn't return anything valuable at all
func TestMultiSyncManyUselessWithLowTimeout ( t * testing . T ) {
func TestMultiSyncManyUselessWithLowTimeout ( t * testing . T ) {
t . Parallel ( )
testMultiSyncManyUselessWithLowTimeout ( t , rawdb . HashScheme )
testMultiSyncManyUselessWithLowTimeout ( t , rawdb . PathScheme )
}
func testMultiSyncManyUselessWithLowTimeout ( t * testing . T , scheme string ) {
var (
var (
once sync . Once
once sync . Once
cancel = make ( chan struct { } )
cancel = make ( chan struct { } )
@ -815,7 +853,7 @@ func TestMultiSyncManyUselessWithLowTimeout(t *testing.T) {
} )
} )
}
}
)
)
nodeScheme , sourceAccountTrie , elems , storageTries , storageElems := makeAccountTrieWithStorage ( 100 , 3000 , true , false )
nodeScheme , sourceAccountTrie , elems , storageTries , storageElems := makeAccountTrieWithStorage ( scheme , 100 , 3000 , true , false )
mkSource := func ( name string , noAccount , noStorage , noTrieNode bool ) * testPeer {
mkSource := func ( name string , noAccount , noStorage , noTrieNode bool ) * testPeer {
source := newTestPeer ( name , t , term )
source := newTestPeer ( name , t , term )
@ -853,11 +891,18 @@ func TestMultiSyncManyUselessWithLowTimeout(t *testing.T) {
t . Fatalf ( "sync failed: %v" , err )
t . Fatalf ( "sync failed: %v" , err )
}
}
close ( done )
close ( done )
verifyTrie ( syncer . db , sourceAccountTrie . Hash ( ) , t )
verifyTrie ( scheme , s yncer . db , sourceAccountTrie . Hash ( ) , t )
}
}
// TestMultiSyncManyUnresponsive contains one good peer, and many which doesn't respond at all
// TestMultiSyncManyUnresponsive contains one good peer, and many which doesn't respond at all
func TestMultiSyncManyUnresponsive ( t * testing . T ) {
func TestMultiSyncManyUnresponsive ( t * testing . T ) {
t . Parallel ( )
testMultiSyncManyUnresponsive ( t , rawdb . HashScheme )
testMultiSyncManyUnresponsive ( t , rawdb . PathScheme )
}
func testMultiSyncManyUnresponsive ( t * testing . T , scheme string ) {
var (
var (
once sync . Once
once sync . Once
cancel = make ( chan struct { } )
cancel = make ( chan struct { } )
@ -867,7 +912,7 @@ func TestMultiSyncManyUnresponsive(t *testing.T) {
} )
} )
}
}
)
)
nodeScheme , sourceAccountTrie , elems , storageTries , storageElems := makeAccountTrieWithStorage ( 100 , 3000 , true , false )
nodeScheme , sourceAccountTrie , elems , storageTries , storageElems := makeAccountTrieWithStorage ( scheme , 100 , 3000 , true , false )
mkSource := func ( name string , noAccount , noStorage , noTrieNode bool ) * testPeer {
mkSource := func ( name string , noAccount , noStorage , noTrieNode bool ) * testPeer {
source := newTestPeer ( name , t , term )
source := newTestPeer ( name , t , term )
@ -903,7 +948,7 @@ func TestMultiSyncManyUnresponsive(t *testing.T) {
t . Fatalf ( "sync failed: %v" , err )
t . Fatalf ( "sync failed: %v" , err )
}
}
close ( done )
close ( done )
verifyTrie ( syncer . db , sourceAccountTrie . Hash ( ) , t )
verifyTrie ( scheme , s yncer . db , sourceAccountTrie . Hash ( ) , t )
}
}
func checkStall ( t * testing . T , term func ( ) ) chan struct { } {
func checkStall ( t * testing . T , term func ( ) ) chan struct { } {
@ -925,6 +970,11 @@ func checkStall(t *testing.T, term func()) chan struct{} {
func TestSyncBoundaryAccountTrie ( t * testing . T ) {
func TestSyncBoundaryAccountTrie ( t * testing . T ) {
t . Parallel ( )
t . Parallel ( )
testSyncBoundaryAccountTrie ( t , rawdb . HashScheme )
testSyncBoundaryAccountTrie ( t , rawdb . PathScheme )
}
func testSyncBoundaryAccountTrie ( t * testing . T , scheme string ) {
var (
var (
once sync . Once
once sync . Once
cancel = make ( chan struct { } )
cancel = make ( chan struct { } )
@ -934,7 +984,7 @@ func TestSyncBoundaryAccountTrie(t *testing.T) {
} )
} )
}
}
)
)
nodeScheme , sourceAccountTrie , elems := makeBoundaryAccountTrie ( 3000 )
nodeScheme , sourceAccountTrie , elems := makeBoundaryAccountTrie ( scheme , 3000 )
mkSource := func ( name string ) * testPeer {
mkSource := func ( name string ) * testPeer {
source := newTestPeer ( name , t , term )
source := newTestPeer ( name , t , term )
@ -952,7 +1002,7 @@ func TestSyncBoundaryAccountTrie(t *testing.T) {
t . Fatalf ( "sync failed: %v" , err )
t . Fatalf ( "sync failed: %v" , err )
}
}
close ( done )
close ( done )
verifyTrie ( syncer . db , sourceAccountTrie . Hash ( ) , t )
verifyTrie ( scheme , s yncer . db , sourceAccountTrie . Hash ( ) , t )
}
}
// TestSyncNoStorageAndOneCappedPeer tests sync using accounts and no storage, where one peer is
// TestSyncNoStorageAndOneCappedPeer tests sync using accounts and no storage, where one peer is
@ -960,6 +1010,11 @@ func TestSyncBoundaryAccountTrie(t *testing.T) {
func TestSyncNoStorageAndOneCappedPeer ( t * testing . T ) {
func TestSyncNoStorageAndOneCappedPeer ( t * testing . T ) {
t . Parallel ( )
t . Parallel ( )
testSyncNoStorageAndOneCappedPeer ( t , rawdb . HashScheme )
testSyncNoStorageAndOneCappedPeer ( t , rawdb . PathScheme )
}
func testSyncNoStorageAndOneCappedPeer ( t * testing . T , scheme string ) {
var (
var (
once sync . Once
once sync . Once
cancel = make ( chan struct { } )
cancel = make ( chan struct { } )
@ -969,7 +1024,7 @@ func TestSyncNoStorageAndOneCappedPeer(t *testing.T) {
} )
} )
}
}
)
)
nodeScheme , sourceAccountTrie , elems := makeAccountTrieNoStorage ( 3000 )
nodeScheme , sourceAccountTrie , elems := makeAccountTrieNoStorage ( 3000 , scheme )
mkSource := func ( name string , slow bool ) * testPeer {
mkSource := func ( name string , slow bool ) * testPeer {
source := newTestPeer ( name , t , term )
source := newTestPeer ( name , t , term )
@ -994,7 +1049,7 @@ func TestSyncNoStorageAndOneCappedPeer(t *testing.T) {
t . Fatalf ( "sync failed: %v" , err )
t . Fatalf ( "sync failed: %v" , err )
}
}
close ( done )
close ( done )
verifyTrie ( syncer . db , sourceAccountTrie . Hash ( ) , t )
verifyTrie ( scheme , s yncer . db , sourceAccountTrie . Hash ( ) , t )
}
}
// TestSyncNoStorageAndOneCodeCorruptPeer has one peer which doesn't deliver
// TestSyncNoStorageAndOneCodeCorruptPeer has one peer which doesn't deliver
@ -1002,6 +1057,11 @@ func TestSyncNoStorageAndOneCappedPeer(t *testing.T) {
func TestSyncNoStorageAndOneCodeCorruptPeer ( t * testing . T ) {
func TestSyncNoStorageAndOneCodeCorruptPeer ( t * testing . T ) {
t . Parallel ( )
t . Parallel ( )
testSyncNoStorageAndOneCodeCorruptPeer ( t , rawdb . HashScheme )
testSyncNoStorageAndOneCodeCorruptPeer ( t , rawdb . PathScheme )
}
func testSyncNoStorageAndOneCodeCorruptPeer ( t * testing . T , scheme string ) {
var (
var (
once sync . Once
once sync . Once
cancel = make ( chan struct { } )
cancel = make ( chan struct { } )
@ -1011,7 +1071,7 @@ func TestSyncNoStorageAndOneCodeCorruptPeer(t *testing.T) {
} )
} )
}
}
)
)
nodeScheme , sourceAccountTrie , elems := makeAccountTrieNoStorage ( 3000 )
nodeScheme , sourceAccountTrie , elems := makeAccountTrieNoStorage ( 3000 , scheme )
mkSource := func ( name string , codeFn codeHandlerFunc ) * testPeer {
mkSource := func ( name string , codeFn codeHandlerFunc ) * testPeer {
source := newTestPeer ( name , t , term )
source := newTestPeer ( name , t , term )
@ -1034,12 +1094,17 @@ func TestSyncNoStorageAndOneCodeCorruptPeer(t *testing.T) {
t . Fatalf ( "sync failed: %v" , err )
t . Fatalf ( "sync failed: %v" , err )
}
}
close ( done )
close ( done )
verifyTrie ( syncer . db , sourceAccountTrie . Hash ( ) , t )
verifyTrie ( scheme , s yncer . db , sourceAccountTrie . Hash ( ) , t )
}
}
func TestSyncNoStorageAndOneAccountCorruptPeer ( t * testing . T ) {
func TestSyncNoStorageAndOneAccountCorruptPeer ( t * testing . T ) {
t . Parallel ( )
t . Parallel ( )
testSyncNoStorageAndOneAccountCorruptPeer ( t , rawdb . HashScheme )
testSyncNoStorageAndOneAccountCorruptPeer ( t , rawdb . PathScheme )
}
func testSyncNoStorageAndOneAccountCorruptPeer ( t * testing . T , scheme string ) {
var (
var (
once sync . Once
once sync . Once
cancel = make ( chan struct { } )
cancel = make ( chan struct { } )
@ -1049,7 +1114,7 @@ func TestSyncNoStorageAndOneAccountCorruptPeer(t *testing.T) {
} )
} )
}
}
)
)
nodeScheme , sourceAccountTrie , elems := makeAccountTrieNoStorage ( 3000 )
nodeScheme , sourceAccountTrie , elems := makeAccountTrieNoStorage ( 3000 , scheme )
mkSource := func ( name string , accFn accountHandlerFunc ) * testPeer {
mkSource := func ( name string , accFn accountHandlerFunc ) * testPeer {
source := newTestPeer ( name , t , term )
source := newTestPeer ( name , t , term )
@ -1072,7 +1137,7 @@ func TestSyncNoStorageAndOneAccountCorruptPeer(t *testing.T) {
t . Fatalf ( "sync failed: %v" , err )
t . Fatalf ( "sync failed: %v" , err )
}
}
close ( done )
close ( done )
verifyTrie ( syncer . db , sourceAccountTrie . Hash ( ) , t )
verifyTrie ( scheme , s yncer . db , sourceAccountTrie . Hash ( ) , t )
}
}
// TestSyncNoStorageAndOneCodeCappedPeer has one peer which delivers code hashes
// TestSyncNoStorageAndOneCodeCappedPeer has one peer which delivers code hashes
@ -1080,6 +1145,11 @@ func TestSyncNoStorageAndOneAccountCorruptPeer(t *testing.T) {
func TestSyncNoStorageAndOneCodeCappedPeer ( t * testing . T ) {
func TestSyncNoStorageAndOneCodeCappedPeer ( t * testing . T ) {
t . Parallel ( )
t . Parallel ( )
testSyncNoStorageAndOneCodeCappedPeer ( t , rawdb . HashScheme )
testSyncNoStorageAndOneCodeCappedPeer ( t , rawdb . PathScheme )
}
func testSyncNoStorageAndOneCodeCappedPeer ( t * testing . T , scheme string ) {
var (
var (
once sync . Once
once sync . Once
cancel = make ( chan struct { } )
cancel = make ( chan struct { } )
@ -1089,7 +1159,7 @@ func TestSyncNoStorageAndOneCodeCappedPeer(t *testing.T) {
} )
} )
}
}
)
)
nodeScheme , sourceAccountTrie , elems := makeAccountTrieNoStorage ( 3000 )
nodeScheme , sourceAccountTrie , elems := makeAccountTrieNoStorage ( 3000 , scheme )
mkSource := func ( name string , codeFn codeHandlerFunc ) * testPeer {
mkSource := func ( name string , codeFn codeHandlerFunc ) * testPeer {
source := newTestPeer ( name , t , term )
source := newTestPeer ( name , t , term )
@ -1123,7 +1193,7 @@ func TestSyncNoStorageAndOneCodeCappedPeer(t *testing.T) {
if threshold := 100 ; counter > threshold {
if threshold := 100 ; counter > threshold {
t . Logf ( "Error, expected < %d invocations, got %d" , threshold , counter )
t . Logf ( "Error, expected < %d invocations, got %d" , threshold , counter )
}
}
verifyTrie ( syncer . db , sourceAccountTrie . Hash ( ) , t )
verifyTrie ( scheme , s yncer . db , sourceAccountTrie . Hash ( ) , t )
}
}
// TestSyncBoundaryStorageTrie tests sync against a few normal peers, but the
// TestSyncBoundaryStorageTrie tests sync against a few normal peers, but the
@ -1131,6 +1201,11 @@ func TestSyncNoStorageAndOneCodeCappedPeer(t *testing.T) {
func TestSyncBoundaryStorageTrie ( t * testing . T ) {
func TestSyncBoundaryStorageTrie ( t * testing . T ) {
t . Parallel ( )
t . Parallel ( )
testSyncBoundaryStorageTrie ( t , rawdb . HashScheme )
testSyncBoundaryStorageTrie ( t , rawdb . PathScheme )
}
func testSyncBoundaryStorageTrie ( t * testing . T , scheme string ) {
var (
var (
once sync . Once
once sync . Once
cancel = make ( chan struct { } )
cancel = make ( chan struct { } )
@ -1140,7 +1215,7 @@ func TestSyncBoundaryStorageTrie(t *testing.T) {
} )
} )
}
}
)
)
nodeScheme , sourceAccountTrie , elems , storageTries , storageElems := makeAccountTrieWithStorage ( 10 , 1000 , false , true )
nodeScheme , sourceAccountTrie , elems , storageTries , storageElems := makeAccountTrieWithStorage ( scheme , 10 , 1000 , false , true )
mkSource := func ( name string ) * testPeer {
mkSource := func ( name string ) * testPeer {
source := newTestPeer ( name , t , term )
source := newTestPeer ( name , t , term )
@ -1160,7 +1235,7 @@ func TestSyncBoundaryStorageTrie(t *testing.T) {
t . Fatalf ( "sync failed: %v" , err )
t . Fatalf ( "sync failed: %v" , err )
}
}
close ( done )
close ( done )
verifyTrie ( syncer . db , sourceAccountTrie . Hash ( ) , t )
verifyTrie ( scheme , s yncer . db , sourceAccountTrie . Hash ( ) , t )
}
}
// TestSyncWithStorageAndOneCappedPeer tests sync using accounts + storage, where one peer is
// TestSyncWithStorageAndOneCappedPeer tests sync using accounts + storage, where one peer is
@ -1168,6 +1243,11 @@ func TestSyncBoundaryStorageTrie(t *testing.T) {
func TestSyncWithStorageAndOneCappedPeer ( t * testing . T ) {
func TestSyncWithStorageAndOneCappedPeer ( t * testing . T ) {
t . Parallel ( )
t . Parallel ( )
testSyncWithStorageAndOneCappedPeer ( t , rawdb . HashScheme )
testSyncWithStorageAndOneCappedPeer ( t , rawdb . PathScheme )
}
func testSyncWithStorageAndOneCappedPeer ( t * testing . T , scheme string ) {
var (
var (
once sync . Once
once sync . Once
cancel = make ( chan struct { } )
cancel = make ( chan struct { } )
@ -1177,7 +1257,7 @@ func TestSyncWithStorageAndOneCappedPeer(t *testing.T) {
} )
} )
}
}
)
)
nodeScheme , sourceAccountTrie , elems , storageTries , storageElems := makeAccountTrieWithStorage ( 300 , 1000 , false , false )
nodeScheme , sourceAccountTrie , elems , storageTries , storageElems := makeAccountTrieWithStorage ( scheme , 300 , 1000 , false , false )
mkSource := func ( name string , slow bool ) * testPeer {
mkSource := func ( name string , slow bool ) * testPeer {
source := newTestPeer ( name , t , term )
source := newTestPeer ( name , t , term )
@ -1202,7 +1282,7 @@ func TestSyncWithStorageAndOneCappedPeer(t *testing.T) {
t . Fatalf ( "sync failed: %v" , err )
t . Fatalf ( "sync failed: %v" , err )
}
}
close ( done )
close ( done )
verifyTrie ( syncer . db , sourceAccountTrie . Hash ( ) , t )
verifyTrie ( scheme , s yncer . db , sourceAccountTrie . Hash ( ) , t )
}
}
// TestSyncWithStorageAndCorruptPeer tests sync using accounts + storage, where one peer is
// TestSyncWithStorageAndCorruptPeer tests sync using accounts + storage, where one peer is
@ -1210,6 +1290,11 @@ func TestSyncWithStorageAndOneCappedPeer(t *testing.T) {
func TestSyncWithStorageAndCorruptPeer ( t * testing . T ) {
func TestSyncWithStorageAndCorruptPeer ( t * testing . T ) {
t . Parallel ( )
t . Parallel ( )
testSyncWithStorageAndCorruptPeer ( t , rawdb . HashScheme )
testSyncWithStorageAndCorruptPeer ( t , rawdb . PathScheme )
}
func testSyncWithStorageAndCorruptPeer ( t * testing . T , scheme string ) {
var (
var (
once sync . Once
once sync . Once
cancel = make ( chan struct { } )
cancel = make ( chan struct { } )
@ -1219,7 +1304,7 @@ func TestSyncWithStorageAndCorruptPeer(t *testing.T) {
} )
} )
}
}
)
)
nodeScheme , sourceAccountTrie , elems , storageTries , storageElems := makeAccountTrieWithStorage ( 100 , 3000 , true , false )
nodeScheme , sourceAccountTrie , elems , storageTries , storageElems := makeAccountTrieWithStorage ( scheme , 100 , 3000 , true , false )
mkSource := func ( name string , handler storageHandlerFunc ) * testPeer {
mkSource := func ( name string , handler storageHandlerFunc ) * testPeer {
source := newTestPeer ( name , t , term )
source := newTestPeer ( name , t , term )
@ -1243,12 +1328,17 @@ func TestSyncWithStorageAndCorruptPeer(t *testing.T) {
t . Fatalf ( "sync failed: %v" , err )
t . Fatalf ( "sync failed: %v" , err )
}
}
close ( done )
close ( done )
verifyTrie ( syncer . db , sourceAccountTrie . Hash ( ) , t )
verifyTrie ( scheme , s yncer . db , sourceAccountTrie . Hash ( ) , t )
}
}
func TestSyncWithStorageAndNonProvingPeer ( t * testing . T ) {
func TestSyncWithStorageAndNonProvingPeer ( t * testing . T ) {
t . Parallel ( )
t . Parallel ( )
testSyncWithStorageAndNonProvingPeer ( t , rawdb . HashScheme )
testSyncWithStorageAndNonProvingPeer ( t , rawdb . PathScheme )
}
func testSyncWithStorageAndNonProvingPeer ( t * testing . T , scheme string ) {
var (
var (
once sync . Once
once sync . Once
cancel = make ( chan struct { } )
cancel = make ( chan struct { } )
@ -1258,7 +1348,7 @@ func TestSyncWithStorageAndNonProvingPeer(t *testing.T) {
} )
} )
}
}
)
)
nodeScheme , sourceAccountTrie , elems , storageTries , storageElems := makeAccountTrieWithStorage ( 100 , 3000 , true , false )
nodeScheme , sourceAccountTrie , elems , storageTries , storageElems := makeAccountTrieWithStorage ( scheme , 100 , 3000 , true , false )
mkSource := func ( name string , handler storageHandlerFunc ) * testPeer {
mkSource := func ( name string , handler storageHandlerFunc ) * testPeer {
source := newTestPeer ( name , t , term )
source := newTestPeer ( name , t , term )
@ -1281,7 +1371,7 @@ func TestSyncWithStorageAndNonProvingPeer(t *testing.T) {
t . Fatalf ( "sync failed: %v" , err )
t . Fatalf ( "sync failed: %v" , err )
}
}
close ( done )
close ( done )
verifyTrie ( syncer . db , sourceAccountTrie . Hash ( ) , t )
verifyTrie ( scheme , s yncer . db , sourceAccountTrie . Hash ( ) , t )
}
}
// TestSyncWithStorage tests basic sync using accounts + storage + code, against
// TestSyncWithStorage tests basic sync using accounts + storage + code, against
@ -1290,6 +1380,12 @@ func TestSyncWithStorageAndNonProvingPeer(t *testing.T) {
// did not mark the account for healing.
// did not mark the account for healing.
func TestSyncWithStorageMisbehavingProve ( t * testing . T ) {
func TestSyncWithStorageMisbehavingProve ( t * testing . T ) {
t . Parallel ( )
t . Parallel ( )
testSyncWithStorageMisbehavingProve ( t , rawdb . HashScheme )
testSyncWithStorageMisbehavingProve ( t , rawdb . PathScheme )
}
func testSyncWithStorageMisbehavingProve ( t * testing . T , scheme string ) {
var (
var (
once sync . Once
once sync . Once
cancel = make ( chan struct { } )
cancel = make ( chan struct { } )
@ -1299,7 +1395,7 @@ func TestSyncWithStorageMisbehavingProve(t *testing.T) {
} )
} )
}
}
)
)
nodeScheme , sourceAccountTrie , elems , storageTries , storageElems := makeAccountTrieWithStorageWithUniqueStorage ( 10 , 30 , false )
nodeScheme , sourceAccountTrie , elems , storageTries , storageElems := makeAccountTrieWithStorageWithUniqueStorage ( scheme , 10 , 30 , false )
mkSource := func ( name string ) * testPeer {
mkSource := func ( name string ) * testPeer {
source := newTestPeer ( name , t , term )
source := newTestPeer ( name , t , term )
@ -1314,7 +1410,7 @@ func TestSyncWithStorageMisbehavingProve(t *testing.T) {
if err := syncer . Sync ( sourceAccountTrie . Hash ( ) , cancel ) ; err != nil {
if err := syncer . Sync ( sourceAccountTrie . Hash ( ) , cancel ) ; err != nil {
t . Fatalf ( "sync failed: %v" , err )
t . Fatalf ( "sync failed: %v" , err )
}
}
verifyTrie ( syncer . db , sourceAccountTrie . Hash ( ) , t )
verifyTrie ( scheme , s yncer . db , sourceAccountTrie . Hash ( ) , t )
}
}
type kv struct {
type kv struct {
@ -1364,9 +1460,9 @@ func getCodeByHash(hash common.Hash) []byte {
}
}
// makeAccountTrieNoStorage spits out a trie, along with the leafs
// makeAccountTrieNoStorage spits out a trie, along with the leafs
func makeAccountTrieNoStorage ( n int ) ( string , * trie . Trie , [ ] * kv ) {
func makeAccountTrieNoStorage ( n int , scheme string ) ( string , * trie . Trie , [ ] * kv ) {
var (
var (
db = trie . NewDatabase ( rawdb . NewMemoryDatabase ( ) )
db = trie . NewDatabase ( rawdb . NewMemoryDatabase ( ) , newDbConfig ( scheme ) )
accTrie = trie . NewEmpty ( db )
accTrie = trie . NewEmpty ( db )
entries [ ] * kv
entries [ ] * kv
)
)
@ -1396,12 +1492,12 @@ func makeAccountTrieNoStorage(n int) (string, *trie.Trie, []*kv) {
// makeBoundaryAccountTrie constructs an account trie. Instead of filling
// makeBoundaryAccountTrie constructs an account trie. Instead of filling
// accounts normally, this function will fill a few accounts which have
// accounts normally, this function will fill a few accounts which have
// boundary hash.
// boundary hash.
func makeBoundaryAccountTrie ( n int ) ( string , * trie . Trie , [ ] * kv ) {
func makeBoundaryAccountTrie ( scheme string , n int ) ( string , * trie . Trie , [ ] * kv ) {
var (
var (
entries [ ] * kv
entries [ ] * kv
boundaries [ ] common . Hash
boundaries [ ] common . Hash
db = trie . NewDatabase ( rawdb . NewMemoryDatabase ( ) )
db = trie . NewDatabase ( rawdb . NewMemoryDatabase ( ) , newDbConfig ( scheme ) )
accTrie = trie . NewEmpty ( db )
accTrie = trie . NewEmpty ( db )
)
)
// Initialize boundaries
// Initialize boundaries
@ -1457,9 +1553,9 @@ func makeBoundaryAccountTrie(n int) (string, *trie.Trie, []*kv) {
// makeAccountTrieWithStorageWithUniqueStorage creates an account trie where each accounts
// makeAccountTrieWithStorageWithUniqueStorage creates an account trie where each accounts
// has a unique storage set.
// has a unique storage set.
func makeAccountTrieWithStorageWithUniqueStorage ( accounts , slots int , code bool ) ( string , * trie . Trie , [ ] * kv , map [ common . Hash ] * trie . Trie , map [ common . Hash ] [ ] * kv ) {
func makeAccountTrieWithStorageWithUniqueStorage ( scheme string , accounts , slots int , code bool ) ( string , * trie . Trie , [ ] * kv , map [ common . Hash ] * trie . Trie , map [ common . Hash ] [ ] * kv ) {
var (
var (
db = trie . NewDatabase ( rawdb . NewMemoryDatabase ( ) )
db = trie . NewDatabase ( rawdb . NewMemoryDatabase ( ) , newDbConfig ( scheme ) )
accTrie = trie . NewEmpty ( db )
accTrie = trie . NewEmpty ( db )
entries [ ] * kv
entries [ ] * kv
storageRoots = make ( map [ common . Hash ] common . Hash )
storageRoots = make ( map [ common . Hash ] common . Hash )
@ -1512,9 +1608,9 @@ func makeAccountTrieWithStorageWithUniqueStorage(accounts, slots int, code bool)
}
}
// makeAccountTrieWithStorage spits out a trie, along with the leafs
// makeAccountTrieWithStorage spits out a trie, along with the leafs
func makeAccountTrieWithStorage ( accounts , slots int , code , boundary bool ) ( string , * trie . Trie , [ ] * kv , map [ common . Hash ] * trie . Trie , map [ common . Hash ] [ ] * kv ) {
func makeAccountTrieWithStorage ( scheme string , accounts , slots int , code , boundary bool ) ( string , * trie . Trie , [ ] * kv , map [ common . Hash ] * trie . Trie , map [ common . Hash ] [ ] * kv ) {
var (
var (
db = trie . NewDatabase ( rawdb . NewMemoryDatabase ( ) )
db = trie . NewDatabase ( rawdb . NewMemoryDatabase ( ) , newDbConfig ( scheme ) )
accTrie = trie . NewEmpty ( db )
accTrie = trie . NewEmpty ( db )
entries [ ] * kv
entries [ ] * kv
storageRoots = make ( map [ common . Hash ] common . Hash )
storageRoots = make ( map [ common . Hash ] common . Hash )
@ -1656,9 +1752,9 @@ func makeBoundaryStorageTrie(owner common.Hash, n int, db *trie.Database) (commo
return root , nodes , entries
return root , nodes , entries
}
}
func verifyTrie ( db ethdb . KeyValueStore , root common . Hash , t * testing . T ) {
func verifyTrie ( scheme string , db ethdb . KeyValueStore , root common . Hash , t * testing . T ) {
t . Helper ( )
t . Helper ( )
triedb := trie . NewDatabase ( rawdb . NewDatabase ( db ) )
triedb := trie . NewDatabase ( rawdb . NewDatabase ( db ) , newDbConfig ( scheme ) )
accTrie , err := trie . New ( trie . StateTrieID ( root ) , triedb )
accTrie , err := trie . New ( trie . StateTrieID ( root ) , triedb )
if err != nil {
if err != nil {
t . Fatal ( err )
t . Fatal ( err )
@ -1700,6 +1796,13 @@ func verifyTrie(db ethdb.KeyValueStore, root common.Hash, t *testing.T) {
// TestSyncAccountPerformance tests how efficient the snap algo is at minimizing
// TestSyncAccountPerformance tests how efficient the snap algo is at minimizing
// state healing
// state healing
func TestSyncAccountPerformance ( t * testing . T ) {
func TestSyncAccountPerformance ( t * testing . T ) {
t . Parallel ( )
testSyncAccountPerformance ( t , rawdb . HashScheme )
testSyncAccountPerformance ( t , rawdb . PathScheme )
}
func testSyncAccountPerformance ( t * testing . T , scheme string ) {
// Set the account concurrency to 1. This _should_ result in the
// Set the account concurrency to 1. This _should_ result in the
// range root to become correct, and there should be no healing needed
// range root to become correct, and there should be no healing needed
defer func ( old int ) { accountConcurrency = old } ( accountConcurrency )
defer func ( old int ) { accountConcurrency = old } ( accountConcurrency )
@ -1714,7 +1817,7 @@ func TestSyncAccountPerformance(t *testing.T) {
} )
} )
}
}
)
)
nodeScheme , sourceAccountTrie , elems := makeAccountTrieNoStorage ( 100 )
nodeScheme , sourceAccountTrie , elems := makeAccountTrieNoStorage ( 100 , scheme )
mkSource := func ( name string ) * testPeer {
mkSource := func ( name string ) * testPeer {
source := newTestPeer ( name , t , term )
source := newTestPeer ( name , t , term )
@ -1727,7 +1830,7 @@ func TestSyncAccountPerformance(t *testing.T) {
if err := syncer . Sync ( sourceAccountTrie . Hash ( ) , cancel ) ; err != nil {
if err := syncer . Sync ( sourceAccountTrie . Hash ( ) , cancel ) ; err != nil {
t . Fatalf ( "sync failed: %v" , err )
t . Fatalf ( "sync failed: %v" , err )
}
}
verifyTrie ( syncer . db , sourceAccountTrie . Hash ( ) , t )
verifyTrie ( scheme , s yncer . db , sourceAccountTrie . Hash ( ) , t )
// The trie root will always be requested, since it is added when the snap
// The trie root will always be requested, since it is added when the snap
// sync cycle starts. When popping the queue, we do not look it up again.
// sync cycle starts. When popping the queue, we do not look it up again.
// Doing so would bring this number down to zero in this artificial testcase,
// Doing so would bring this number down to zero in this artificial testcase,
@ -1787,3 +1890,10 @@ func TestSlotEstimation(t *testing.T) {
}
}
}
}
}
}
func newDbConfig ( scheme string ) * trie . Config {
if scheme == rawdb . HashScheme {
return & trie . Config { }
}
return & trie . Config { PathDB : pathdb . Defaults }
}