Skip to content

Commit

Permalink
Create HandlerBlockchain
Browse files Browse the repository at this point in the history
  • Loading branch information
quentinlesceller committed Aug 17, 2022
1 parent fbdcb59 commit 1caef5b
Show file tree
Hide file tree
Showing 10 changed files with 104 additions and 31 deletions.
18 changes: 16 additions & 2 deletions eth/handler.go
Expand Up @@ -80,7 +80,7 @@ type HandlerConfig handlerConfig
// node network handler.
type handlerConfig struct {
Database ethdb.Database // Database for direct sync insertions
Chain *core.BlockChain // Blockchain to serve data from
Chain eth.HandlerBlockchain // Blockchain to serve data from
TxPool txPool // Transaction pool to propagate from
Merger *consensus.Merger // The manager for eth1/2 transition
Network uint64 // Network identifier to adfvertise
Expand All @@ -91,6 +91,20 @@ type handlerConfig struct {
RequiredBlocks map[uint64]common.Hash // Hard coded map of required block hashes for sync challenges
}

type Handler handler

func (h *Handler) BroadcastTransactions(txs types.Transactions) {
(*handler)(h).BroadcastTransactions(txs)
}

func (h *Handler) PeerCount() int {
return h.peers.len()
}

func (h *Handler) Start(maxPeers int) {
(*handler)(h).Start(maxPeers)
}

type handler struct {
networkID uint64
forkFilter forkid.Filter // Fork ID filter, constant across the lifetime of the node
Expand All @@ -103,7 +117,7 @@ type handler struct {

database ethdb.Database
txpool txPool
chain *core.BlockChain
chain eth.HandlerBlockchain
maxPeers int

downloader *downloader.Downloader
Expand Down
5 changes: 2 additions & 3 deletions eth/handler_eth.go
Expand Up @@ -23,7 +23,6 @@ import (
"time"

"github.com/blockcypher/go-ethereum/common"
"github.com/blockcypher/go-ethereum/core"
"github.com/blockcypher/go-ethereum/core/types"
"github.com/blockcypher/go-ethereum/eth/protocols/eth"
"github.com/blockcypher/go-ethereum/p2p/enode"
Expand All @@ -33,8 +32,8 @@ import (
// packets that are sent as replies or broadcasts.
type ethHandler handler

func (h *ethHandler) Chain() *core.BlockChain { return h.chain }
func (h *ethHandler) TxPool() eth.TxPool { return h.txpool }
func (h *ethHandler) Chain() eth.HandlerBlockchain { return h.chain }
func (h *ethHandler) TxPool() eth.TxPool { return h.txpool }

// RunPeer is invoked when a peer joins on the `eth` protocol.
func (h *ethHandler) RunPeer(peer *eth.Peer, hand eth.Handler) error {
Expand Down
2 changes: 1 addition & 1 deletion eth/handler_eth_test.go
Expand Up @@ -49,7 +49,7 @@ type testEthHandler struct {
txBroadcasts event.Feed
}

func (h *testEthHandler) Chain() *core.BlockChain { panic("no backing chain") }
func (h *testEthHandler) Chain() eth.HandlerBlockchain { panic("no backing chain") }
func (h *testEthHandler) TxPool() eth.TxPool { panic("no backing tx pool") }
func (h *testEthHandler) AcceptTxs() bool { return true }
func (h *testEthHandler) RunPeer(*eth.Peer, eth.Handler) error { panic("not used in tests") }
Expand Down
4 changes: 2 additions & 2 deletions eth/handler_snap.go
Expand Up @@ -17,7 +17,7 @@
package eth

import (
"github.com/blockcypher/go-ethereum/core"
"github.com/blockcypher/go-ethereum/eth/protocols/eth"
"github.com/blockcypher/go-ethereum/eth/protocols/snap"
"github.com/blockcypher/go-ethereum/p2p/enode"
)
Expand All @@ -26,7 +26,7 @@ import (
// packets that are sent as replies or broadcasts.
type snapHandler handler

func (h *snapHandler) Chain() *core.BlockChain { return h.chain }
func (h *snapHandler) Chain() eth.HandlerBlockchain { return h.chain }

// RunPeer is invoked when a peer joins on the `snap` protocol.
func (h *snapHandler) RunPeer(peer *snap.Peer, hand snap.Handler) error {
Expand Down
4 changes: 2 additions & 2 deletions eth/protocols/eth/discovery.go
Expand Up @@ -38,7 +38,7 @@ func (e enrEntry) ENRKey() string {

// StartENRUpdater starts the `eth` ENR updater loop, which listens for chain
// head events and updates the requested node record whenever a fork is passed.
func StartENRUpdater(chain *core.BlockChain, ln *enode.LocalNode) {
func StartENRUpdater(chain HandlerBlockchain, ln *enode.LocalNode) {
var newHead = make(chan core.ChainHeadEvent, 10)
sub := chain.SubscribeChainHeadEvent(newHead)

Expand All @@ -58,7 +58,7 @@ func StartENRUpdater(chain *core.BlockChain, ln *enode.LocalNode) {
}

// currentENREntry constructs an `eth` ENR entry based on the current state of the chain.
func currentENREntry(chain *core.BlockChain) *enrEntry {
func currentENREntry(chain HandlerBlockchain) *enrEntry {
return &enrEntry{
ForkID: forkid.NewID(chain.Config(), chain.Genesis().Hash(), chain.CurrentHeader().Number.Uint64()),
}
Expand Down
64 changes: 62 additions & 2 deletions eth/protocols/eth/handler.go
Expand Up @@ -22,13 +22,18 @@ import (
"time"

"github.com/blockcypher/go-ethereum/common"
"github.com/blockcypher/go-ethereum/consensus"
"github.com/blockcypher/go-ethereum/core"
"github.com/blockcypher/go-ethereum/core/state"
"github.com/blockcypher/go-ethereum/core/state/snapshot"
"github.com/blockcypher/go-ethereum/core/types"
"github.com/blockcypher/go-ethereum/event"
"github.com/blockcypher/go-ethereum/metrics"
"github.com/blockcypher/go-ethereum/p2p"
"github.com/blockcypher/go-ethereum/p2p/enode"
"github.com/blockcypher/go-ethereum/p2p/enr"
"github.com/blockcypher/go-ethereum/params"
"github.com/blockcypher/go-ethereum/rlp"
)

const (
Expand All @@ -55,6 +60,61 @@ const (
maxReceiptsServe = 1024
)

type HandlerBlockchain interface {
SetHead(head uint64) error
CurrentBlock() *types.Block
CurrentFastBlock() *types.Block
Genesis() *types.Block

HasBlock(hash common.Hash, number uint64) bool
HasFastBlock(hash common.Hash, number uint64) bool
GetBlock(hash common.Hash, number uint64) *types.Block
GetBlockByHash(hash common.Hash) *types.Block
StopInsert()
InsertBlockWithoutSetHead(block *types.Block) error
InsertReceiptChain(blockChain types.Blocks, receiptChain []types.Receipts, ancientLimit uint64) (int, error)

SetTxLookupLimit(limit uint64)
TxLookupLimit() uint64

InsertChain(chain types.Blocks) (int, error)

InsertHeaderChain(chain []*types.Header, checkFreq int) (int, error)
CurrentHeader() *types.Header
GetTd(hash common.Hash, number uint64) *big.Int
GetHeader(hash common.Hash, number uint64) *types.Header
GetHeaderByHash(hash common.Hash) *types.Header
GetHeadersFrom(number, count uint64) []rlp.RawValue
HasHeader(hash common.Hash, number uint64) bool
GetHeaderByNumber(number uint64) *types.Header

Config() *params.ChainConfig
Engine() consensus.Engine

// Additionnal func for particular handler
// required by snap
SnapSyncCommitHead(common.Hash) error
Snapshots() *snapshot.Tree
ContractCode(hash common.Hash) ([]byte, error)
StateCache() state.Database

// required by discovery.go
SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription

// required by eth/handlers.go
GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64)
GetBodyRLP(hash common.Hash) rlp.RawValue
TrieNode(hash common.Hash) ([]byte, error)
ContractCodeWithPrefix(hash common.Hash) ([]byte, error)
GetReceiptsByHash(hash common.Hash) types.Receipts

// required for eth/handler_test.go
GetBlockByNumber(number uint64) *types.Block
GetCanonicalHash(number uint64) common.Hash
StateAt(root common.Hash) (*state.StateDB, error)
Stop()
}

// Handler is a callback to invoke from an outside runner after the boilerplate
// exchanges have passed.
type Handler func(peer *Peer) error
Expand All @@ -63,7 +123,7 @@ type Handler func(peer *Peer) error
// callback methods to invoke on remote deliveries.
type Backend interface {
// Chain retrieves the blockchain object to serve data.
Chain() *core.BlockChain
Chain() HandlerBlockchain

// TxPool retrieves the transaction pool object to serve data.
TxPool() TxPool
Expand Down Expand Up @@ -135,7 +195,7 @@ type NodeInfo struct {
}

// nodeInfo retrieves some `eth` protocol metadata about the running host node.
func nodeInfo(chain *core.BlockChain, network uint64) *NodeInfo {
func nodeInfo(chain HandlerBlockchain, network uint64) *NodeInfo {
head := chain.CurrentBlock()
return &NodeInfo{
Network: network,
Expand Down
6 changes: 3 additions & 3 deletions eth/protocols/eth/handler_test.go
Expand Up @@ -49,7 +49,7 @@ var (
// in the `eth` protocol without actually doing any data processing.
type testBackend struct {
db ethdb.Database
chain *core.BlockChain
chain HandlerBlockchain
txpool *core.TxPool
}

Expand Down Expand Up @@ -90,8 +90,8 @@ func (b *testBackend) close() {
b.chain.Stop()
}

func (b *testBackend) Chain() *core.BlockChain { return b.chain }
func (b *testBackend) TxPool() TxPool { return b.txpool }
func (b *testBackend) Chain() HandlerBlockchain { return b.chain }
func (b *testBackend) TxPool() TxPool { return b.txpool }

func (b *testBackend) RunPeer(peer *Peer, handler Handler) error {
// Normally the backend would do peer mainentance and handshakes. All that
Expand Down
13 changes: 6 additions & 7 deletions eth/protocols/eth/handlers.go
Expand Up @@ -21,7 +21,6 @@ import (
"fmt"

"github.com/blockcypher/go-ethereum/common"
"github.com/blockcypher/go-ethereum/core"
"github.com/blockcypher/go-ethereum/core/types"
"github.com/blockcypher/go-ethereum/log"
"github.com/blockcypher/go-ethereum/rlp"
Expand All @@ -41,7 +40,7 @@ func handleGetBlockHeaders66(backend Backend, msg Decoder, peer *Peer) error {

// ServiceGetBlockHeadersQuery assembles the response to a header query. It is
// exposed to allow external packages to test protocol behavior.
func ServiceGetBlockHeadersQuery(chain *core.BlockChain, query *GetBlockHeadersPacket, peer *Peer) []rlp.RawValue {
func ServiceGetBlockHeadersQuery(chain HandlerBlockchain, query *GetBlockHeadersPacket, peer *Peer) []rlp.RawValue {
if query.Skip == 0 {
// The fast path: when the request is for a contiguous segment of headers.
return serviceContiguousBlockHeaderQuery(chain, query)
Expand All @@ -50,7 +49,7 @@ func ServiceGetBlockHeadersQuery(chain *core.BlockChain, query *GetBlockHeadersP
}
}

func serviceNonContiguousBlockHeaderQuery(chain *core.BlockChain, query *GetBlockHeadersPacket, peer *Peer) []rlp.RawValue {
func serviceNonContiguousBlockHeaderQuery(chain HandlerBlockchain, query *GetBlockHeadersPacket, peer *Peer) []rlp.RawValue {
hashMode := query.Origin.Hash != (common.Hash{})
first := true
maxNonCanonical := uint64(100)
Expand Down Expand Up @@ -139,7 +138,7 @@ func serviceNonContiguousBlockHeaderQuery(chain *core.BlockChain, query *GetBloc
return headers
}

func serviceContiguousBlockHeaderQuery(chain *core.BlockChain, query *GetBlockHeadersPacket) []rlp.RawValue {
func serviceContiguousBlockHeaderQuery(chain HandlerBlockchain, query *GetBlockHeadersPacket) []rlp.RawValue {
count := query.Amount
if count > maxHeadersServe {
count = maxHeadersServe
Expand Down Expand Up @@ -214,7 +213,7 @@ func handleGetBlockBodies66(backend Backend, msg Decoder, peer *Peer) error {

// ServiceGetBlockBodiesQuery assembles the response to a body query. It is
// exposed to allow external packages to test protocol behavior.
func ServiceGetBlockBodiesQuery(chain *core.BlockChain, query GetBlockBodiesPacket) []rlp.RawValue {
func ServiceGetBlockBodiesQuery(chain HandlerBlockchain, query GetBlockBodiesPacket) []rlp.RawValue {
// Gather blocks until the fetch or network limits is reached
var (
bytes int
Expand Down Expand Up @@ -245,7 +244,7 @@ func handleGetNodeData66(backend Backend, msg Decoder, peer *Peer) error {

// ServiceGetNodeDataQuery assembles the response to a node data query. It is
// exposed to allow external packages to test protocol behavior.
func ServiceGetNodeDataQuery(chain *core.BlockChain, query GetNodeDataPacket) [][]byte {
func ServiceGetNodeDataQuery(chain HandlerBlockchain, query GetNodeDataPacket) [][]byte {
// Gather state data until the fetch or network limits is reached
var (
bytes int
Expand Down Expand Up @@ -282,7 +281,7 @@ func handleGetReceipts66(backend Backend, msg Decoder, peer *Peer) error {

// ServiceGetReceiptsQuery assembles the response to a receipt query. It is
// exposed to allow external packages to test protocol behavior.
func ServiceGetReceiptsQuery(chain *core.BlockChain, query GetReceiptsPacket) []rlp.RawValue {
func ServiceGetReceiptsQuery(chain HandlerBlockchain, query GetReceiptsPacket) []rlp.RawValue {
// Gather state data until the fetch or network limits is reached
var (
bytes int
Expand Down
14 changes: 7 additions & 7 deletions eth/protocols/snap/handler.go
Expand Up @@ -22,8 +22,8 @@ import (
"time"

"github.com/blockcypher/go-ethereum/common"
"github.com/blockcypher/go-ethereum/core"
"github.com/blockcypher/go-ethereum/core/types"
"github.com/blockcypher/go-ethereum/eth/protocols/eth"
"github.com/blockcypher/go-ethereum/light"
"github.com/blockcypher/go-ethereum/log"
"github.com/blockcypher/go-ethereum/metrics"
Expand Down Expand Up @@ -65,7 +65,7 @@ type Handler func(peer *Peer) error
// callback methods to invoke on remote deliveries.
type Backend interface {
// Chain retrieves the blockchain object to serve data.
Chain() *core.BlockChain
Chain() eth.HandlerBlockchain

// RunPeer is invoked when a peer joins on the `eth` protocol. The handler
// should do any peer maintenance work, handshakes and validations. If all
Expand Down Expand Up @@ -280,7 +280,7 @@ func HandleMessage(backend Backend, peer *Peer) error {

// ServiceGetAccountRangeQuery assembles the response to an account range query.
// It is exposed to allow external packages to test protocol behavior.
func ServiceGetAccountRangeQuery(chain *core.BlockChain, req *GetAccountRangePacket) ([]*AccountData, [][]byte) {
func ServiceGetAccountRangeQuery(chain eth.HandlerBlockchain, req *GetAccountRangePacket) ([]*AccountData, [][]byte) {
if req.Bytes > softResponseLimit {
req.Bytes = softResponseLimit
}
Expand Down Expand Up @@ -340,7 +340,7 @@ func ServiceGetAccountRangeQuery(chain *core.BlockChain, req *GetAccountRangePac
return accounts, proofs
}

func ServiceGetStorageRangesQuery(chain *core.BlockChain, req *GetStorageRangesPacket) ([][]*StorageData, [][]byte) {
func ServiceGetStorageRangesQuery(chain eth.HandlerBlockchain, req *GetStorageRangesPacket) ([][]*StorageData, [][]byte) {
if req.Bytes > softResponseLimit {
req.Bytes = softResponseLimit
}
Expand Down Expand Up @@ -452,7 +452,7 @@ func ServiceGetStorageRangesQuery(chain *core.BlockChain, req *GetStorageRangesP

// ServiceGetByteCodesQuery assembles the response to a byte codes query.
// It is exposed to allow external packages to test protocol behavior.
func ServiceGetByteCodesQuery(chain *core.BlockChain, req *GetByteCodesPacket) [][]byte {
func ServiceGetByteCodesQuery(chain eth.HandlerBlockchain, req *GetByteCodesPacket) [][]byte {
if req.Bytes > softResponseLimit {
req.Bytes = softResponseLimit
}
Expand Down Expand Up @@ -482,7 +482,7 @@ func ServiceGetByteCodesQuery(chain *core.BlockChain, req *GetByteCodesPacket) [

// ServiceGetTrieNodesQuery assembles the response to a trie nodes query.
// It is exposed to allow external packages to test protocol behavior.
func ServiceGetTrieNodesQuery(chain *core.BlockChain, req *GetTrieNodesPacket, start time.Time) ([][]byte, error) {
func ServiceGetTrieNodesQuery(chain eth.HandlerBlockchain, req *GetTrieNodesPacket, start time.Time) ([][]byte, error) {
if req.Bytes > softResponseLimit {
req.Bytes = softResponseLimit
}
Expand Down Expand Up @@ -564,6 +564,6 @@ func ServiceGetTrieNodesQuery(chain *core.BlockChain, req *GetTrieNodesPacket, s
type NodeInfo struct{}

// nodeInfo retrieves some `snap` protocol metadata about the running host node.
func nodeInfo(chain *core.BlockChain) *NodeInfo {
func nodeInfo(chain eth.HandlerBlockchain) *NodeInfo {
return &NodeInfo{}
}
5 changes: 3 additions & 2 deletions tests/fuzzers/snap/fuzz_handler.go
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/blockcypher/go-ethereum/core"
"github.com/blockcypher/go-ethereum/core/rawdb"
"github.com/blockcypher/go-ethereum/core/vm"
"github.com/blockcypher/go-ethereum/eth/protocols/eth"
"github.com/blockcypher/go-ethereum/eth/protocols/snap"
"github.com/blockcypher/go-ethereum/p2p"
"github.com/blockcypher/go-ethereum/p2p/enode"
Expand Down Expand Up @@ -87,10 +88,10 @@ func getChain() *core.BlockChain {
}

type dummyBackend struct {
chain *core.BlockChain
chain eth.HandlerBlockchain
}

func (d *dummyBackend) Chain() *core.BlockChain { return d.chain }
func (d *dummyBackend) Chain() eth.HandlerBlockchain { return d.chain }
func (d *dummyBackend) RunPeer(*snap.Peer, snap.Handler) error { return nil }
func (d *dummyBackend) PeerInfo(enode.ID) interface{} { return "Foo" }
func (d *dummyBackend) Handle(*snap.Peer, snap.Packet) error { return nil }
Expand Down

0 comments on commit 1caef5b

Please sign in to comment.