forked from cerc-io/plugeth
core, eth, internal, rpc: implement final block (#24282)
* eth: core: implement finalized block * eth/catalyst: fix final block * eth/catalyst: update finalized head gauge * internal/jsre/deps: updated web3.js to allow for finalized block * eth/catalyst: make sure only one thread can call fcu * eth/catalyst: nitpicks * eth/catalyst: use plain mutex * eth: nitpicks
This commit is contained in:
@@ -285,6 +285,8 @@ func (api *PublicDebugAPI) DumpBlock(blockNr rpc.BlockNumber) (state.Dump, error
|
||||
var block *types.Block
|
||||
if blockNr == rpc.LatestBlockNumber {
|
||||
block = api.eth.blockchain.CurrentBlock()
|
||||
} else if blockNr == rpc.FinalizedBlockNumber {
|
||||
block = api.eth.blockchain.CurrentFinalizedBlock()
|
||||
} else {
|
||||
block = api.eth.blockchain.GetBlockByNumber(uint64(blockNr))
|
||||
}
|
||||
@@ -373,6 +375,8 @@ func (api *PublicDebugAPI) AccountRange(blockNrOrHash rpc.BlockNumberOrHash, sta
|
||||
var block *types.Block
|
||||
if number == rpc.LatestBlockNumber {
|
||||
block = api.eth.blockchain.CurrentBlock()
|
||||
} else if number == rpc.FinalizedBlockNumber {
|
||||
block = api.eth.blockchain.CurrentFinalizedBlock()
|
||||
} else {
|
||||
block = api.eth.blockchain.GetBlockByNumber(uint64(number))
|
||||
}
|
||||
|
||||
@@ -73,6 +73,9 @@ func (b *EthAPIBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumb
|
||||
if number == rpc.LatestBlockNumber {
|
||||
return b.eth.blockchain.CurrentBlock().Header(), nil
|
||||
}
|
||||
if number == rpc.FinalizedBlockNumber {
|
||||
return b.eth.blockchain.CurrentFinalizedBlock().Header(), nil
|
||||
}
|
||||
return b.eth.blockchain.GetHeaderByNumber(uint64(number)), nil
|
||||
}
|
||||
|
||||
@@ -107,6 +110,9 @@ func (b *EthAPIBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumbe
|
||||
if number == rpc.LatestBlockNumber {
|
||||
return b.eth.blockchain.CurrentBlock(), nil
|
||||
}
|
||||
if number == rpc.FinalizedBlockNumber {
|
||||
return b.eth.blockchain.CurrentFinalizedBlock(), nil
|
||||
}
|
||||
return b.eth.blockchain.GetBlockByNumber(uint64(number)), nil
|
||||
}
|
||||
|
||||
|
||||
+11
-2
@@ -22,6 +22,7 @@ import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
@@ -60,6 +61,8 @@ type ConsensusAPI struct {
|
||||
eth *eth.Ethereum
|
||||
remoteBlocks *headerQueue // Cache of remote payloads received
|
||||
localBlocks *payloadQueue // Cache of local payloads generated
|
||||
// Lock for the forkChoiceUpdated method
|
||||
forkChoiceLock sync.Mutex
|
||||
}
|
||||
|
||||
// NewConsensusAPI creates a new consensus api for the given backend.
|
||||
@@ -86,11 +89,15 @@ func NewConsensusAPI(eth *eth.Ethereum) *ConsensusAPI {
|
||||
// If there are payloadAttributes:
|
||||
// we try to assemble a block with the payloadAttributes and return its payloadID
|
||||
func (api *ConsensusAPI) ForkchoiceUpdatedV1(update beacon.ForkchoiceStateV1, payloadAttributes *beacon.PayloadAttributesV1) (beacon.ForkChoiceResponse, error) {
|
||||
api.forkChoiceLock.Lock()
|
||||
defer api.forkChoiceLock.Unlock()
|
||||
|
||||
log.Trace("Engine API request received", "method", "ForkchoiceUpdated", "head", update.HeadBlockHash, "finalized", update.FinalizedBlockHash, "safe", update.SafeBlockHash)
|
||||
if update.HeadBlockHash == (common.Hash{}) {
|
||||
log.Warn("Forkchoice requested update to zero hash")
|
||||
return beacon.STATUS_INVALID, nil // TODO(karalabe): Why does someone send us this?
|
||||
}
|
||||
|
||||
// Check whether we have the block yet in our database or not. If not, we'll
|
||||
// need to either trigger a sync, or to reject this forkchoice update for a
|
||||
// reason.
|
||||
@@ -154,7 +161,7 @@ func (api *ConsensusAPI) ForkchoiceUpdatedV1(update beacon.ForkchoiceStateV1, pa
|
||||
if merger := api.eth.Merger(); !merger.PoSFinalized() {
|
||||
merger.FinalizePoS()
|
||||
}
|
||||
// TODO (MariusVanDerWijden): If the finalized block is not in our canonical tree, somethings wrong
|
||||
// If the finalized block is not in our canonical tree, somethings wrong
|
||||
finalBlock := api.eth.BlockChain().GetBlockByHash(update.FinalizedBlockHash)
|
||||
if finalBlock == nil {
|
||||
log.Warn("Final block not available in database", "hash", update.FinalizedBlockHash)
|
||||
@@ -163,8 +170,10 @@ func (api *ConsensusAPI) ForkchoiceUpdatedV1(update beacon.ForkchoiceStateV1, pa
|
||||
log.Warn("Final block not in canonical chain", "number", block.NumberU64(), "hash", update.HeadBlockHash)
|
||||
return beacon.STATUS_INVALID, errors.New("final block not canonical")
|
||||
}
|
||||
// Set the finalized block
|
||||
api.eth.BlockChain().SetFinalized(finalBlock)
|
||||
}
|
||||
// TODO (MariusVanDerWijden): Check if the safe block hash is in our canonical tree, if not somethings wrong
|
||||
// Check if the safe block hash is in our canonical tree, if not somethings wrong
|
||||
if update.SafeBlockHash != (common.Hash{}) {
|
||||
safeBlock := api.eth.BlockChain().GetBlockByHash(update.SafeBlockHash)
|
||||
if safeBlock == nil {
|
||||
|
||||
@@ -476,7 +476,10 @@ func TestFullAPI(t *testing.T) {
|
||||
t.Fatalf("Failed to insert block: %v", err)
|
||||
}
|
||||
if ethservice.BlockChain().CurrentBlock().NumberU64() != payload.Number {
|
||||
t.Fatalf("Chain head should be updated")
|
||||
t.Fatal("Chain head should be updated")
|
||||
}
|
||||
if ethservice.BlockChain().CurrentFinalizedBlock().NumberU64() != payload.Number-1 {
|
||||
t.Fatal("Finalized block should be updated")
|
||||
}
|
||||
parent = ethservice.BlockChain().CurrentBlock()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user