-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
consortium-v2/snapshot: make FindAncientHeader more readable
This commit refactors FindAncientHeader, changes its name to findAncestorHeader, adds some comments and unit test to make the code more readable.
- Loading branch information
Showing
2 changed files
with
155 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
package v2 | ||
|
||
import ( | ||
"math/big" | ||
"testing" | ||
|
||
"github.com/ethereum/go-ethereum/common" | ||
"github.com/ethereum/go-ethereum/core/state" | ||
"github.com/ethereum/go-ethereum/core/types" | ||
"github.com/ethereum/go-ethereum/core/vm" | ||
"github.com/ethereum/go-ethereum/ethdb" | ||
"github.com/ethereum/go-ethereum/params" | ||
) | ||
|
||
type mockChainReader struct { | ||
headerMapping map[common.Hash]*types.Header | ||
} | ||
|
||
func (chainReader *mockChainReader) Config() *params.ChainConfig { return nil } | ||
func (chainReader *mockChainReader) CurrentHeader() *types.Header { return nil } | ||
func (chainReader *mockChainReader) GetHeader(hash common.Hash, number uint64) *types.Header { | ||
return chainReader.headerMapping[hash] | ||
} | ||
func (chainReader *mockChainReader) GetHeaderByNumber(number uint64) *types.Header { return nil } | ||
func (chainReader *mockChainReader) GetHeaderByHash(hash common.Hash) *types.Header { return nil } | ||
func (chainReader *mockChainReader) DB() ethdb.Database { return nil } | ||
func (chainReader *mockChainReader) StateCache() state.Database { return nil } | ||
func (chainReader *mockChainReader) OpEvents() []*vm.PublishEvent { return nil } | ||
|
||
func TestFindCheckpointHeader(t *testing.T) { | ||
// Case 1: checkpoint header is in parent list | ||
parents := make([]*types.Header, 10) | ||
for i := range parents { | ||
parents[i] = &types.Header{Number: big.NewInt(int64(i)), Coinbase: common.BigToAddress(big.NewInt(int64(i)))} | ||
} | ||
|
||
checkpointHeader := findAncestorHeader(5, nil, parents, nil) | ||
if checkpointHeader.Number.Cmp(big.NewInt(5)) != 0 && checkpointHeader.Coinbase != common.BigToAddress(big.NewInt(5)) { | ||
t.Fatalf("Expect checkpoint header number: %d, got: %d", 5, checkpointHeader.Number.Int64()) | ||
} | ||
|
||
// Case 2: checkpoint header is higher than parent list, this must not happen | ||
// but the function must not crash in this case | ||
checkpointHeader = findAncestorHeader(11, nil, parents, nil) | ||
if checkpointHeader != nil { | ||
t.Fatalf("Expect %v checkpoint header, got %v", nil, checkpointHeader) | ||
} | ||
|
||
// Case 3: checkpoint header is lower than parent list | ||
// parent list ranges from [10, 20) | ||
for i := range parents { | ||
parents[i] = &types.Header{Number: big.NewInt(int64(i + 10)), ParentHash: common.BigToHash(big.NewInt(int64(i + 10 - 1)))} | ||
} | ||
mockChain := mockChainReader{ | ||
headerMapping: make(map[common.Hash]*types.Header), | ||
} | ||
// create mock chain 1 | ||
for i := 5; i < 10; i++ { | ||
mockChain.headerMapping[common.BigToHash(big.NewInt(int64(100+i)))] = &types.Header{ | ||
Number: big.NewInt(int64(i)), | ||
ParentHash: common.BigToHash(big.NewInt(int64(100 + i - 1))), | ||
} | ||
} | ||
|
||
// create mock chain 2 | ||
for i := 5; i < 10; i++ { | ||
mockChain.headerMapping[common.BigToHash(big.NewInt(int64(i)))] = &types.Header{ | ||
Number: big.NewInt(int64(i)), | ||
ParentHash: common.BigToHash(big.NewInt(int64(i - 1))), | ||
} | ||
} | ||
|
||
// Must traverse and get the correct header in chain 2 | ||
checkpointHeader = findAncestorHeader(5, &mockChain, parents, nil) | ||
if checkpointHeader == nil { | ||
t.Fatal("Failed to find checkpoint header") | ||
} | ||
if checkpointHeader.Number.Cmp(big.NewInt(5)) != 0 && checkpointHeader.ParentHash != common.BigToHash(big.NewInt(int64(4))) { | ||
t.Fatalf("Expect checkpoint header number %d, parent hash: %s, got number: %d, parent hash: %s", | ||
5, common.BigToHash(big.NewInt(int64(4))), | ||
checkpointHeader.Number.Int64(), checkpointHeader.ParentHash, | ||
) | ||
} | ||
|
||
// Case 4: find checkpoint header with nil parent list | ||
checkpointHeader = findAncestorHeader( | ||
5, | ||
&mockChain, | ||
nil, | ||
&types.Header{Number: big.NewInt(10), ParentHash: common.BigToHash(big.NewInt(109))}, | ||
) | ||
// Must traverse and get the correct header in chain 1 | ||
if checkpointHeader == nil { | ||
t.Fatal("Failed to find checkpoint header") | ||
} | ||
if checkpointHeader.Number.Cmp(big.NewInt(5)) != 0 && checkpointHeader.ParentHash != common.BigToHash(big.NewInt(int64(104))) { | ||
t.Fatalf("Expect checkpoint header number %d, parent hash: %s, got number: %d, parent hash: %s", | ||
5, common.BigToHash(big.NewInt(int64(104))), | ||
checkpointHeader.Number.Int64(), checkpointHeader.ParentHash, | ||
) | ||
} | ||
} |