Skip to content

Commit

Permalink
Merge pull request ethereum#23 from karalabe/merge-interop-spec-sync4
Browse files Browse the repository at this point in the history
core, eth: various tiny fixups integrating sync
  • Loading branch information
MariusVanDerWijden authored Oct 4, 2021
2 parents 716ff95 + 7834589 commit 56bebd7
Show file tree
Hide file tree
Showing 8 changed files with 31 additions and 68 deletions.
5 changes: 1 addition & 4 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,10 +244,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
engine: engine,
vmConfig: vmConfig,
}
bc.forker = NewForkChoice(bc, merger.LeftPoW(), shouldPreserve)
merger.SubscribeLeavePoW(func() {
bc.forker.MarkTransitioned()
})
bc.forker = NewForkChoice(bc, shouldPreserve)
bc.validator = NewBlockValidator(chainConfig, bc, engine)
bc.prefetcher = newStatePrefetcher(chainConfig, bc, engine)
bc.processor = NewStateProcessor(chainConfig, bc, engine)
Expand Down
8 changes: 0 additions & 8 deletions core/blockchain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,9 +230,6 @@ func testInsertAfterMerge(t *testing.T, blockchain *BlockChain, i, n int, full b
t.Errorf("chain content mismatch at %d: have hash %v, want hash %v", i, hash2, hash1)
}

// Trigger the transition explicitly
blockchain2.forker.MarkTransitioned()

// Extend the newly created chain
if full {
blockChainB := makeBlockChain(blockchain2.CurrentBlock(), n, ethash.NewFaker(), db, forkSeed)
Expand Down Expand Up @@ -1963,7 +1960,6 @@ func testSideImport(t *testing.T, numCanonBlocksInSidechain, blocksBetweenCommon
if mergePoint == 0 {
genEngine.MarkTransitioned()
runEngine.MarkTransitioned()
chain.forker.MarkTransitioned()
}
blocks, _ := GenerateChain(params.TestChainConfig, genesis, genEngine, db, 2*TriesInMemory, func(i int, gen *BlockGen) {
tx, err := types.SignTx(types.NewTransaction(nonce, common.HexToAddress("deadbeef"), big.NewInt(100), 21000, big.NewInt(int64(i+1)*params.GWei), nil), signer, key)
Expand Down Expand Up @@ -1994,7 +1990,6 @@ func testSideImport(t *testing.T, numCanonBlocksInSidechain, blocksBetweenCommon
if mergePoint == 1 {
genEngine.MarkTransitioned()
runEngine.MarkTransitioned()
chain.forker.MarkTransitioned()
}

// Generate the sidechain
Expand Down Expand Up @@ -2218,9 +2213,6 @@ func testInsertKnownChainDataWithMerging(t *testing.T, typ string, mergeHeight i
if engine != nil {
engine.MarkTransitioned()
}
if forker != nil {
forker.MarkTransitioned()
}
}

// Apply merging since genesis
Expand Down
40 changes: 15 additions & 25 deletions core/forkchoice.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,16 @@ import (
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
)

// ChainReader defines a small collection of methods needed to access the local
// blockchain during header verification. It's implemented by both blockchain
// and lightchain.
type ChainReader interface {
// Config retrieves the header chain's chain configuration.
Config() *params.ChainConfig

// GetTd returns the total difficulty of a local block.
GetTd(common.Hash, uint64) *big.Int
}
Expand All @@ -45,12 +49,7 @@ type ChainReader interface {
type ForkChoice struct {
chain ChainReader
rand *mrand.Rand

// transitioned is the flag whether the chain has started(or finished)
// the transition. It's triggered by receiving the first "NewHead" message
// from the external consensus engine.
transitioned bool
lock sync.RWMutex
lock sync.RWMutex

// preserve is a helper function used in td fork choice.
// Miners will prefer to choose the local mined block if the
Expand All @@ -59,17 +58,16 @@ type ForkChoice struct {
preserve func(header *types.Header) bool
}

func NewForkChoice(chainReader ChainReader, transitioned bool, preserve func(header *types.Header) bool) *ForkChoice {
func NewForkChoice(chainReader ChainReader, preserve func(header *types.Header) bool) *ForkChoice {
// Seed a fast but crypto originating random generator
seed, err := crand.Int(crand.Reader, big.NewInt(math.MaxInt64))
if err != nil {
log.Crit("Failed to initialize random seed", "err", err)
}
return &ForkChoice{
chain: chainReader,
rand: mrand.New(mrand.NewSource(seed.Int64())),
transitioned: transitioned,
preserve: preserve,
chain: chainReader,
rand: mrand.New(mrand.NewSource(seed.Int64())),
preserve: preserve,
}
}

Expand All @@ -82,19 +80,19 @@ func (f *ForkChoice) Reorg(current *types.Header, header *types.Header) (bool, e
f.lock.RLock()
defer f.lock.RUnlock()

// Accept the new header as the chain head if the transition
// is already triggered. We assume all the headers after the
// transition come from the trusted consensus layer.
if f.transitioned {
return true, nil
}
var (
localTD = f.chain.GetTd(current.Hash(), current.Number.Uint64())
externTd = f.chain.GetTd(header.Hash(), header.Number.Uint64())
)
if localTD == nil || externTd == nil {
return false, errors.New("missing td")
}
// Accept the new header as the chain head if the transition
// is already triggered. We assume all the headers after the
// transition come from the trusted consensus layer.
if ttd := f.chain.Config().TerminalTotalDifficulty; ttd != nil && ttd.Cmp(externTd) <= 0 {
return true, nil
}
// If the total difficulty is higher than our known, add it to the canonical chain
// Second clause in the if statement reduces the vulnerability to selfish mining.
// Please refer to http://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf
Expand All @@ -113,11 +111,3 @@ func (f *ForkChoice) Reorg(current *types.Header, header *types.Header) (bool, e
}
return reorg, nil
}

// MarkTransitioned marks the transition has started.
func (f *ForkChoice) MarkTransitioned() {
f.lock.Lock()
defer f.lock.Unlock()

f.transitioned = true
}
2 changes: 1 addition & 1 deletion core/headerchain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func TestHeaderInsertion(t *testing.T) {
chainB := makeHeaderChain(chainA[0], 128, ethash.NewFaker(), db, 10)
log.Root().SetHandler(log.StdoutHandler)

forker := NewForkChoice(hc, false, nil)
forker := NewForkChoice(hc, nil)
// Inserting 64 headers on an empty chain, expecting
// 1 callbacks, 1 canon-status, 0 sidestatus,
testInsert(t, hc, chainA[:64], CanonStatTy, nil, forker)
Expand Down
25 changes: 9 additions & 16 deletions eth/catalyst/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ func (api *ConsensusAPI) ExecutePayload(params ExecutableData) (GenericStringRes
if parent == nil {
return INVALID, fmt.Errorf("could not find parent %x", params.ParentHash)
}
block, err := ExecutableDataToBlock(api.les.BlockChain().Config(), parent, params)
block, err := ExecutableDataToBlock(params)
if err != nil {
return INVALID, err
}
Expand All @@ -240,17 +240,7 @@ func (api *ConsensusAPI) ExecutePayload(params ExecutableData) (GenericStringRes
}
return VALID, nil
}
parent := api.eth.BlockChain().GetBlockByHash(params.ParentHash)
if parent == nil {
return INVALID, fmt.Errorf("could not find parent %x", params.ParentHash)
}

td := api.eth.BlockChain().GetTdByHash(parent.Hash())
ttd := api.eth.BlockChain().Config().TerminalTotalDifficulty
if td.Cmp(ttd) < 0 {
return INVALID, fmt.Errorf("can not execute payload on top of block with low td got: %v threshold %v", td, ttd)
}
block, err := ExecutableDataToBlock(api.eth.BlockChain().Config(), parent.Header(), params)
block, err := ExecutableDataToBlock(params)
if err != nil {
return INVALID, err
}
Expand All @@ -260,6 +250,12 @@ func (api *ConsensusAPI) ExecutePayload(params ExecutableData) (GenericStringRes
}
return SYNCING, nil
}
parent := api.eth.BlockChain().GetBlockByHash(params.ParentHash)
td := api.eth.BlockChain().GetTdByHash(parent.Hash())
ttd := api.eth.BlockChain().Config().TerminalTotalDifficulty
if td.Cmp(ttd) < 0 {
return INVALID, fmt.Errorf("can not execute payload on top of block with low td got: %v threshold %v", td, ttd)
}
if err := api.eth.BlockChain().InsertBlock(block); err != nil {
return INVALID, err
}
Expand Down Expand Up @@ -392,7 +388,7 @@ func decodeTransactions(enc [][]byte) ([]*types.Transaction, error) {
return txs, nil
}

func ExecutableDataToBlock(config *chainParams.ChainConfig, parent *types.Header, params ExecutableData) (*types.Block, error) {
func ExecutableDataToBlock(params ExecutableData) (*types.Block, error) {
txs, err := decodeTransactions(params.Transactions)
if err != nil {
return nil, err
Expand All @@ -419,9 +415,6 @@ func ExecutableDataToBlock(config *chainParams.ChainConfig, parent *types.Header
Extra: params.ExtraData,
// TODO (MariusVanDerWijden) add params.Random to header once required
}
if config.IsLondon(number) {
header.BaseFee = misc.CalcBaseFee(config, parent)
}
block := types.NewBlockWithHeader(header).WithBody(txs, nil /* uncles */)
if block.Hash() != params.BlockHash {
return nil, fmt.Errorf("blockhash mismatch, want %x, got %x", params.BlockHash, block.Hash())
Expand Down
4 changes: 2 additions & 2 deletions eth/catalyst/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ func TestEth2NewBlock(t *testing.T) {
if err != nil {
t.Fatalf("Failed to create the executable data %v", err)
}
block, err := ExecutableDataToBlock(ethservice.BlockChain().Config(), parent.Header(), *execData)
block, err := ExecutableDataToBlock(*execData)
if err != nil {
t.Fatalf("Failed to convert executable data to block %v", err)
}
Expand Down Expand Up @@ -292,7 +292,7 @@ func TestEth2NewBlock(t *testing.T) {
if err != nil {
t.Fatalf("Failed to create the executable data %v", err)
}
block, err := ExecutableDataToBlock(ethservice.BlockChain().Config(), parent.Header(), *execData)
block, err := ExecutableDataToBlock(*execData)
if err != nil {
t.Fatalf("Failed to convert executable data to block %v", err)
}
Expand Down
5 changes: 1 addition & 4 deletions light/lightchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,7 @@ func NewLightChain(odr OdrBackend, config *params.ChainConfig, engine consensus.
blockCache: blockCache,
engine: engine,
}
bc.forker = core.NewForkChoice(bc, merger.LeftPoW(), nil)
merger.SubscribeLeavePoW(func() {
bc.forker.MarkTransitioned()
})
bc.forker = core.NewForkChoice(bc, nil)
var err error
bc.hc, err = core.NewHeaderChain(odr.Database(), config, bc.engine, bc.getProcInterrupt)
if err != nil {
Expand Down
10 changes: 2 additions & 8 deletions miner/stress/beacon/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,13 +172,7 @@ func (n *ethNode) insertBlockAndSetHead(parent *types.Header, ed catalyst.Execut
if err := n.insertBlock(ed); err != nil {
return err
}
var config *params.ChainConfig
if n.typ == eth2LightClient {
config = n.lesBackend.BlockChain().Config()
} else {
config = n.ethBackend.BlockChain().Config()
}
block, err := catalyst.ExecutableDataToBlock(config, parent, ed)
block, err := catalyst.ExecutableDataToBlock(ed)
if err != nil {
return err
}
Expand Down Expand Up @@ -319,7 +313,7 @@ func (mgr *nodeManager) run() {
log.Error("Failed to assemble the block", "err", err)
continue
}
block, _ := catalyst.ExecutableDataToBlock(chain.Config(), parentBlock.Header(), *ed)
block, _ := catalyst.ExecutableDataToBlock(*ed)

nodes := mgr.getNodes(eth2MiningNode)
nodes = append(nodes, mgr.getNodes(eth2NormalNode)...)
Expand Down

0 comments on commit 56bebd7

Please sign in to comment.