mirror of https://github.com/ethereum/go-ethereum
consensus/beacon: check that only the latest pow block is valid ttd block (#25187)
* consensus/beacon: check that only the latest pow block is valid ttd block * consensus/beacon: move verification to async function * consensus/beacon: fix verifyTerminalPoWBlock, add test cases * consensus/beacon: cosmetic changes * consensus/beacon: apply karalabe's fixespull/25201/head
parent
c2070f8d15
commit
d12b1a91cd
@ -0,0 +1,137 @@ |
|||||||
|
package beacon |
||||||
|
|
||||||
|
import ( |
||||||
|
"fmt" |
||||||
|
"math/big" |
||||||
|
"testing" |
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common" |
||||||
|
"github.com/ethereum/go-ethereum/consensus" |
||||||
|
"github.com/ethereum/go-ethereum/core/types" |
||||||
|
"github.com/ethereum/go-ethereum/params" |
||||||
|
) |
||||||
|
|
||||||
|
type mockChain struct { |
||||||
|
config *params.ChainConfig |
||||||
|
tds map[uint64]*big.Int |
||||||
|
} |
||||||
|
|
||||||
|
func newMockChain() *mockChain { |
||||||
|
return &mockChain{ |
||||||
|
config: new(params.ChainConfig), |
||||||
|
tds: make(map[uint64]*big.Int), |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func (m *mockChain) Config() *params.ChainConfig { |
||||||
|
return m.config |
||||||
|
} |
||||||
|
|
||||||
|
func (m *mockChain) CurrentHeader() *types.Header { panic("not implemented") } |
||||||
|
|
||||||
|
func (m *mockChain) GetHeader(hash common.Hash, number uint64) *types.Header { |
||||||
|
panic("not implemented") |
||||||
|
} |
||||||
|
|
||||||
|
func (m *mockChain) GetHeaderByNumber(number uint64) *types.Header { panic("not implemented") } |
||||||
|
|
||||||
|
func (m *mockChain) GetHeaderByHash(hash common.Hash) *types.Header { panic("not implemented") } |
||||||
|
|
||||||
|
func (m *mockChain) GetTd(hash common.Hash, number uint64) *big.Int { |
||||||
|
num, ok := m.tds[number] |
||||||
|
if ok { |
||||||
|
return new(big.Int).Set(num) |
||||||
|
} |
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
func TestVerifyTerminalBlock(t *testing.T) { |
||||||
|
chain := newMockChain() |
||||||
|
chain.tds[0] = big.NewInt(10) |
||||||
|
chain.config.TerminalTotalDifficulty = big.NewInt(50) |
||||||
|
|
||||||
|
tests := []struct { |
||||||
|
preHeaders []*types.Header |
||||||
|
ttd *big.Int |
||||||
|
err error |
||||||
|
index int |
||||||
|
}{ |
||||||
|
// valid ttd
|
||||||
|
{ |
||||||
|
preHeaders: []*types.Header{ |
||||||
|
{Number: big.NewInt(1), Difficulty: big.NewInt(10)}, |
||||||
|
{Number: big.NewInt(2), Difficulty: big.NewInt(10)}, |
||||||
|
{Number: big.NewInt(3), Difficulty: big.NewInt(10)}, |
||||||
|
{Number: big.NewInt(4), Difficulty: big.NewInt(10)}, |
||||||
|
}, |
||||||
|
ttd: big.NewInt(50), |
||||||
|
}, |
||||||
|
// last block doesn't reach ttd
|
||||||
|
{ |
||||||
|
preHeaders: []*types.Header{ |
||||||
|
{Number: big.NewInt(1), Difficulty: big.NewInt(10)}, |
||||||
|
{Number: big.NewInt(2), Difficulty: big.NewInt(10)}, |
||||||
|
{Number: big.NewInt(3), Difficulty: big.NewInt(10)}, |
||||||
|
{Number: big.NewInt(4), Difficulty: big.NewInt(9)}, |
||||||
|
}, |
||||||
|
ttd: big.NewInt(50), |
||||||
|
err: consensus.ErrInvalidTerminalBlock, |
||||||
|
index: 3, |
||||||
|
}, |
||||||
|
// two blocks reach ttd
|
||||||
|
{ |
||||||
|
preHeaders: []*types.Header{ |
||||||
|
{Number: big.NewInt(1), Difficulty: big.NewInt(10)}, |
||||||
|
{Number: big.NewInt(2), Difficulty: big.NewInt(10)}, |
||||||
|
{Number: big.NewInt(3), Difficulty: big.NewInt(20)}, |
||||||
|
{Number: big.NewInt(4), Difficulty: big.NewInt(10)}, |
||||||
|
}, |
||||||
|
ttd: big.NewInt(50), |
||||||
|
err: consensus.ErrInvalidTerminalBlock, |
||||||
|
index: 3, |
||||||
|
}, |
||||||
|
// three blocks reach ttd
|
||||||
|
{ |
||||||
|
preHeaders: []*types.Header{ |
||||||
|
{Number: big.NewInt(1), Difficulty: big.NewInt(10)}, |
||||||
|
{Number: big.NewInt(2), Difficulty: big.NewInt(10)}, |
||||||
|
{Number: big.NewInt(3), Difficulty: big.NewInt(20)}, |
||||||
|
{Number: big.NewInt(4), Difficulty: big.NewInt(10)}, |
||||||
|
{Number: big.NewInt(4), Difficulty: big.NewInt(10)}, |
||||||
|
}, |
||||||
|
ttd: big.NewInt(50), |
||||||
|
err: consensus.ErrInvalidTerminalBlock, |
||||||
|
index: 3, |
||||||
|
}, |
||||||
|
// parent reached ttd
|
||||||
|
{ |
||||||
|
preHeaders: []*types.Header{ |
||||||
|
{Number: big.NewInt(1), Difficulty: big.NewInt(10)}, |
||||||
|
}, |
||||||
|
ttd: big.NewInt(9), |
||||||
|
err: consensus.ErrInvalidTerminalBlock, |
||||||
|
index: 0, |
||||||
|
}, |
||||||
|
// unknown parent
|
||||||
|
{ |
||||||
|
preHeaders: []*types.Header{ |
||||||
|
{Number: big.NewInt(4), Difficulty: big.NewInt(10)}, |
||||||
|
}, |
||||||
|
ttd: big.NewInt(9), |
||||||
|
err: consensus.ErrUnknownAncestor, |
||||||
|
index: 0, |
||||||
|
}, |
||||||
|
} |
||||||
|
|
||||||
|
for i, test := range tests { |
||||||
|
fmt.Printf("Test: %v\n", i) |
||||||
|
chain.config.TerminalTotalDifficulty = test.ttd |
||||||
|
index, err := verifyTerminalPoWBlock(chain, test.preHeaders) |
||||||
|
if err != test.err { |
||||||
|
t.Fatalf("Invalid error encountered, expected %v got %v", test.err, err) |
||||||
|
} |
||||||
|
if index != test.index { |
||||||
|
t.Fatalf("Invalid index, expected %v got %v", test.index, index) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue