les: introduce forkID (#21974)

* les: introduce forkID

* les: address comment
This commit is contained in:
gary rong
2020-12-11 00:20:55 +08:00
committed by GitHub
parent b44f24e3e6
commit 004541098d
5 changed files with 68 additions and 21 deletions

View File

@ -29,6 +29,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/mclock"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/forkid"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/les/flowcontrol"
@ -246,7 +247,7 @@ func (p *peerCommons) sendReceiveHandshake(sendList keyValueList) (keyValueList,
// network IDs, difficulties, head and genesis blocks. Besides the basic handshake
// fields, server and client can exchange and resolve some specified fields through
// two callback functions.
func (p *peerCommons) handshake(td *big.Int, head common.Hash, headNum uint64, genesis common.Hash, sendCallback func(*keyValueList), recvCallback func(keyValueMap) error) error {
func (p *peerCommons) handshake(td *big.Int, head common.Hash, headNum uint64, genesis common.Hash, forkID forkid.ID, forkFilter forkid.Filter, sendCallback func(*keyValueList), recvCallback func(keyValueMap) error) error {
p.lock.Lock()
defer p.lock.Unlock()
@ -262,6 +263,12 @@ func (p *peerCommons) handshake(td *big.Int, head common.Hash, headNum uint64, g
send = send.add("headNum", headNum)
send = send.add("genesisHash", genesis)
// If the protocol version is beyond les4, then pass the forkID
// as well. Check http://eips.ethereum.org/EIPS/eip-2124 for more
// spec detail.
if p.version >= lpv4 {
send = send.add("forkID", forkID)
}
// Add client-specified or server-specified fields
if sendCallback != nil {
sendCallback(&send)
@ -295,6 +302,16 @@ func (p *peerCommons) handshake(td *big.Int, head common.Hash, headNum uint64, g
if int(rVersion) != p.version {
return errResp(ErrProtocolVersionMismatch, "%d (!= %d)", rVersion, p.version)
}
// Check forkID if the protocol version is beyond the les4
if p.version >= lpv4 {
var forkID forkid.ID
if err := recv.get("forkID", &forkID); err != nil {
return err
}
if err := forkFilter(forkID); err != nil {
return errResp(ErrForkIDRejected, "%v", err)
}
}
if recvCallback != nil {
return recvCallback(recv)
}
@ -561,10 +578,10 @@ func (p *serverPeer) updateHead(hash common.Hash, number uint64, td *big.Int) {
// Handshake executes the les protocol handshake, negotiating version number,
// network IDs and genesis blocks.
func (p *serverPeer) Handshake(genesis common.Hash) error {
func (p *serverPeer) Handshake(genesis common.Hash, forkid forkid.ID, forkFilter forkid.Filter) error {
// Note: there is no need to share local head with a server but older servers still
// require these fields so we announce zero values.
return p.handshake(common.Big0, common.Hash{}, 0, genesis, func(lists *keyValueList) {
return p.handshake(common.Big0, common.Hash{}, 0, genesis, forkid, forkFilter, func(lists *keyValueList) {
// Add some client-specific handshake fields
//
// Enable signed announcement randomly even the server is not trusted.
@ -944,11 +961,11 @@ func (p *clientPeer) freezeClient() {
// Handshake executes the les protocol handshake, negotiating version number,
// network IDs, difficulties, head and genesis blocks.
func (p *clientPeer) Handshake(td *big.Int, head common.Hash, headNum uint64, genesis common.Hash, server *LesServer) error {
func (p *clientPeer) Handshake(td *big.Int, head common.Hash, headNum uint64, genesis common.Hash, forkID forkid.ID, forkFilter forkid.Filter, server *LesServer) error {
// Note: clientPeer.headInfo should contain the last head announced to the client by us.
// The values announced in the handshake are dummy values for compatibility reasons and should be ignored.
p.headInfo = blockInfo{Hash: head, Number: headNum, Td: td}
return p.handshake(td, head, headNum, genesis, func(lists *keyValueList) {
return p.handshake(td, head, headNum, genesis, forkID, forkFilter, func(lists *keyValueList) {
// Add some information which services server can offer.
if !server.config.UltraLightOnlyAnnounce {
*lists = (*lists).add("serveHeaders", nil)