mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-15 00:13:46 +00:00
feat:beacon network test
Signed-off-by: Chen Kai <281165273grape@gmail.com>
This commit is contained in:
parent
5cc962afc7
commit
eb3206b1e1
9 changed files with 468 additions and 249 deletions
|
|
@ -384,14 +384,14 @@ func (p *PortalProtocolAPI) FindContent(enr string, contentKey string) (interfac
|
||||||
Content: hexutil.Encode(findContent.([]byte)),
|
Content: hexutil.Encode(findContent.([]byte)),
|
||||||
UtpTransfer: false,
|
UtpTransfer: false,
|
||||||
}
|
}
|
||||||
p.portalProtocol.log.Trace("FindContent", "contentInfo", contentInfo)
|
p.portalProtocol.Log.Trace("FindContent", "contentInfo", contentInfo)
|
||||||
return contentInfo, nil
|
return contentInfo, nil
|
||||||
case portalwire.ContentConnIdSelector:
|
case portalwire.ContentConnIdSelector:
|
||||||
contentInfo := &ContentInfo{
|
contentInfo := &ContentInfo{
|
||||||
Content: hexutil.Encode(findContent.([]byte)),
|
Content: hexutil.Encode(findContent.([]byte)),
|
||||||
UtpTransfer: true,
|
UtpTransfer: true,
|
||||||
}
|
}
|
||||||
p.portalProtocol.log.Trace("FindContent", "contentInfo", contentInfo)
|
p.portalProtocol.Log.Trace("FindContent", "contentInfo", contentInfo)
|
||||||
return contentInfo, nil
|
return contentInfo, nil
|
||||||
default:
|
default:
|
||||||
enrs := make([]string, 0)
|
enrs := make([]string, 0)
|
||||||
|
|
@ -399,7 +399,7 @@ func (p *PortalProtocolAPI) FindContent(enr string, contentKey string) (interfac
|
||||||
enrs = append(enrs, r.String())
|
enrs = append(enrs, r.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
p.portalProtocol.log.Trace("FindContent", "enrs", enrs)
|
p.portalProtocol.Log.Trace("FindContent", "enrs", enrs)
|
||||||
return &Enrs{
|
return &Enrs{
|
||||||
Enrs: enrs,
|
Enrs: enrs,
|
||||||
}, nil
|
}, nil
|
||||||
|
|
@ -515,7 +515,7 @@ func (p *PortalProtocolAPI) Gossip(contentKeyHex, contentHex string) (int, error
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
id := p.portalProtocol.Self().ID()
|
id := p.portalProtocol.Self().ID()
|
||||||
return p.portalProtocol.NeighborhoodGossip(&id, [][]byte{contentKey}, [][]byte{content})
|
return p.portalProtocol.Gossip(&id, [][]byte{contentKey}, [][]byte{content})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PortalProtocolAPI) TraceRecursiveFindContent(contentKeyHex string) (*TraceContentResult, error) {
|
func (p *PortalProtocolAPI) TraceRecursiveFindContent(contentKeyHex string) (*TraceContentResult, error) {
|
||||||
|
|
|
||||||
|
|
@ -165,7 +165,7 @@ type PortalProtocol struct {
|
||||||
packetRouter *utp.PacketRouter
|
packetRouter *utp.PacketRouter
|
||||||
ListenAddr string
|
ListenAddr string
|
||||||
localNode *enode.LocalNode
|
localNode *enode.LocalNode
|
||||||
log log.Logger
|
Log log.Logger
|
||||||
PrivateKey *ecdsa.PrivateKey
|
PrivateKey *ecdsa.PrivateKey
|
||||||
NetRestrict *netutil.Netlist
|
NetRestrict *netutil.Netlist
|
||||||
BootstrapNodes []*enode.Node
|
BootstrapNodes []*enode.Node
|
||||||
|
|
@ -193,7 +193,7 @@ func NewPortalProtocol(config *PortalProtocolConfig, protocolId string, privateK
|
||||||
protocol := &PortalProtocol{
|
protocol := &PortalProtocol{
|
||||||
protocolId: protocolId,
|
protocolId: protocolId,
|
||||||
ListenAddr: config.ListenAddr,
|
ListenAddr: config.ListenAddr,
|
||||||
log: log.New("protocol", protocolId),
|
Log: log.New("protocol", protocolId),
|
||||||
PrivateKey: privateKey,
|
PrivateKey: privateKey,
|
||||||
NetRestrict: config.NetRestrict,
|
NetRestrict: config.NetRestrict,
|
||||||
BootstrapNodes: config.BootstrapNodes,
|
BootstrapNodes: config.BootstrapNodes,
|
||||||
|
|
@ -244,7 +244,7 @@ func (p *PortalProtocol) Stop() {
|
||||||
p.DiscV5.Close()
|
p.DiscV5.Close()
|
||||||
err := p.utp.Close()
|
err := p.utp.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to close utp listener", "err", err)
|
p.Log.Error("failed to close utp listener", "err", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (p *PortalProtocol) RoutingTableInfo() [][]string {
|
func (p *PortalProtocol) RoutingTableInfo() [][]string {
|
||||||
|
|
@ -258,14 +258,14 @@ func (p *PortalProtocol) RoutingTableInfo() [][]string {
|
||||||
}
|
}
|
||||||
nodes = append(nodes, bucketNodes)
|
nodes = append(nodes, bucketNodes)
|
||||||
}
|
}
|
||||||
p.log.Trace("routingTableInfo resp:", "nodes", nodes)
|
p.Log.Trace("routingTableInfo resp:", "nodes", nodes)
|
||||||
return nodes
|
return nodes
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PortalProtocol) setupUDPListening() error {
|
func (p *PortalProtocol) setupUDPListening() error {
|
||||||
laddr := p.conn.LocalAddr().(*net.UDPAddr)
|
laddr := p.conn.LocalAddr().(*net.UDPAddr)
|
||||||
p.localNode.SetFallbackUDP(laddr.Port)
|
p.localNode.SetFallbackUDP(laddr.Port)
|
||||||
p.log.Debug("UDP listener up", "addr", laddr)
|
p.Log.Debug("UDP listener up", "addr", laddr)
|
||||||
// TODO: NAT
|
// TODO: NAT
|
||||||
//if !laddr.IP.IsLoopback() && !laddr.IP.IsPrivate() {
|
//if !laddr.IP.IsLoopback() && !laddr.IP.IsPrivate() {
|
||||||
// srv.portMappingRegister <- &portMapping{
|
// srv.portMappingRegister <- &portMapping{
|
||||||
|
|
@ -298,14 +298,14 @@ func (p *PortalProtocol) setupUDPListening() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p.log.Trace("send to target data", "ip", target.IP().String(), "port", target.UDP(), "bufLength", len(buf))
|
p.Log.Trace("send to target data", "ip", target.IP().String(), "port", target.UDP(), "bufLength", len(buf))
|
||||||
_, err := p.DiscV5.TalkRequest(target, string(portalwire.UTPNetwork), buf)
|
_, err := p.DiscV5.TalkRequest(target, string(portalwire.UTPNetwork), buf)
|
||||||
return len(buf), err
|
return len(buf), err
|
||||||
})
|
})
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
var logger *zap.Logger
|
var logger *zap.Logger
|
||||||
if p.log.Enabled(ctx, log.LevelDebug) || p.log.Enabled(ctx, log.LevelTrace) {
|
if p.Log.Enabled(ctx, log.LevelDebug) || p.Log.Enabled(ctx, log.LevelTrace) {
|
||||||
logger, err = zap.NewDevelopmentConfig().Build()
|
logger, err = zap.NewDevelopmentConfig().Build()
|
||||||
} else {
|
} else {
|
||||||
logger, err = zap.NewProductionConfig().Build()
|
logger, err = zap.NewProductionConfig().Build()
|
||||||
|
|
@ -336,7 +336,7 @@ func (p *PortalProtocol) setupDiscV5AndTable() error {
|
||||||
PrivateKey: p.PrivateKey,
|
PrivateKey: p.PrivateKey,
|
||||||
NetRestrict: p.NetRestrict,
|
NetRestrict: p.NetRestrict,
|
||||||
Bootnodes: p.BootstrapNodes,
|
Bootnodes: p.BootstrapNodes,
|
||||||
Log: p.log,
|
Log: p.Log,
|
||||||
}
|
}
|
||||||
|
|
||||||
p.table, err = newMeteredTable(p, p.localNode.Database(), cfg)
|
p.table, err = newMeteredTable(p, p.localNode.Database(), cfg)
|
||||||
|
|
@ -376,7 +376,7 @@ func (p *PortalProtocol) pingInner(node *enode.Node) (*portalwire.Pong, error) {
|
||||||
CustomPayload: customPayloadBytes,
|
CustomPayload: customPayloadBytes,
|
||||||
}
|
}
|
||||||
|
|
||||||
p.log.Trace("Sending ping request", "protocol", p.protocolId, "ip", p.Self().IP().String(), "source", p.Self().ID(), "target", node.ID(), "ping", pingRequest)
|
p.Log.Trace("Sending ping request", "protocol", p.protocolId, "ip", p.Self().IP().String(), "source", p.Self().ID(), "target", node.ID(), "ping", pingRequest)
|
||||||
pingRequestBytes, err := pingRequest.MarshalSSZ()
|
pingRequestBytes, err := pingRequest.MarshalSSZ()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -389,12 +389,12 @@ func (p *PortalProtocol) pingInner(node *enode.Node) (*portalwire.Pong, error) {
|
||||||
talkResp, err := p.DiscV5.TalkRequest(node, p.protocolId, talkRequestBytes)
|
talkResp, err := p.DiscV5.TalkRequest(node, p.protocolId, talkRequestBytes)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("ping error:", err)
|
p.Log.Error("ping error:", err)
|
||||||
p.replaceNode(node)
|
p.replaceNode(node)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
p.log.Trace("Received ping response", "source", p.Self().ID(), "target", node.ID(), "res", talkResp)
|
p.Log.Trace("Received ping response", "source", p.Self().ID(), "target", node.ID(), "res", talkResp)
|
||||||
|
|
||||||
return p.processPong(node, talkResp)
|
return p.processPong(node, talkResp)
|
||||||
}
|
}
|
||||||
|
|
@ -409,10 +409,10 @@ func (p *PortalProtocol) findNodes(node *enode.Node, distances []uint) ([]*enode
|
||||||
Distances: distancesBytes,
|
Distances: distancesBytes,
|
||||||
}
|
}
|
||||||
|
|
||||||
p.log.Trace("Sending find nodes request", "id", node.ID(), "findNodes", findNodes)
|
p.Log.Trace("Sending find nodes request", "id", node.ID(), "findNodes", findNodes)
|
||||||
findNodesBytes, err := findNodes.MarshalSSZ()
|
findNodesBytes, err := findNodes.MarshalSSZ()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to marshal find nodes request", "err", err)
|
p.Log.Error("failed to marshal find nodes request", "err", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -422,7 +422,7 @@ func (p *PortalProtocol) findNodes(node *enode.Node, distances []uint) ([]*enode
|
||||||
|
|
||||||
talkResp, err := p.DiscV5.TalkRequest(node, p.protocolId, talkRequestBytes)
|
talkResp, err := p.DiscV5.TalkRequest(node, p.protocolId, talkRequestBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to send find nodes request", "err", err)
|
p.Log.Error("failed to send find nodes request", "err", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -434,10 +434,10 @@ func (p *PortalProtocol) findContent(node *enode.Node, contentKey []byte) (byte,
|
||||||
ContentKey: contentKey,
|
ContentKey: contentKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
p.log.Trace("Sending find content request", "id", node.ID(), "findContent", findContent)
|
p.Log.Trace("Sending find content request", "id", node.ID(), "findContent", findContent)
|
||||||
findContentBytes, err := findContent.MarshalSSZ()
|
findContentBytes, err := findContent.MarshalSSZ()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to marshal find content request", "err", err)
|
p.Log.Error("failed to marshal find content request", "err", err)
|
||||||
return 0xff, nil, err
|
return 0xff, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -447,7 +447,7 @@ func (p *PortalProtocol) findContent(node *enode.Node, contentKey []byte) (byte,
|
||||||
|
|
||||||
talkResp, err := p.DiscV5.TalkRequest(node, p.protocolId, talkRequestBytes)
|
talkResp, err := p.DiscV5.TalkRequest(node, p.protocolId, talkRequestBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to send find content request", "err", err)
|
p.Log.Error("failed to send find content request", "err", err)
|
||||||
return 0xff, nil, err
|
return 0xff, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -461,10 +461,10 @@ func (p *PortalProtocol) offer(node *enode.Node, offerRequest *OfferRequest) ([]
|
||||||
ContentKeys: contentKeys,
|
ContentKeys: contentKeys,
|
||||||
}
|
}
|
||||||
|
|
||||||
p.log.Trace("Sending offer request", "offer", offer)
|
p.Log.Trace("Sending offer request", "offer", offer)
|
||||||
offerBytes, err := offer.MarshalSSZ()
|
offerBytes, err := offer.MarshalSSZ()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to marshal offer request", "err", err)
|
p.Log.Error("failed to marshal offer request", "err", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -474,7 +474,7 @@ func (p *PortalProtocol) offer(node *enode.Node, offerRequest *OfferRequest) ([]
|
||||||
|
|
||||||
talkResp, err := p.DiscV5.TalkRequest(node, p.protocolId, talkRequestBytes)
|
talkResp, err := p.DiscV5.TalkRequest(node, p.protocolId, talkRequestBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to send offer request", "err", err)
|
p.Log.Error("failed to send offer request", "err", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -493,7 +493,7 @@ func (p *PortalProtocol) processOffer(target *enode.Node, resp []byte, request *
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
p.log.Trace("Received accept response", "id", target.ID(), "accept", accept)
|
p.Log.Trace("Received accept response", "id", target.ID(), "accept", accept)
|
||||||
p.setJustSeen(target)
|
p.setJustSeen(target)
|
||||||
|
|
||||||
var contentKeyLen int
|
var contentKeyLen int
|
||||||
|
|
@ -534,7 +534,7 @@ func (p *PortalProtocol) processOffer(target *enode.Node, resp []byte, request *
|
||||||
if contentId != nil {
|
if contentId != nil {
|
||||||
content, err = p.storage.Get(contentKey, contentId)
|
content, err = p.storage.Get(contentKey, contentId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to get content from storage", "err", err)
|
p.Log.Error("failed to get content from storage", "err", err)
|
||||||
contents = append(contents, []byte{})
|
contents = append(contents, []byte{})
|
||||||
} else {
|
} else {
|
||||||
contents = append(contents, content)
|
contents = append(contents, content)
|
||||||
|
|
@ -548,7 +548,7 @@ func (p *PortalProtocol) processOffer(target *enode.Node, resp []byte, request *
|
||||||
var contentsPayload []byte
|
var contentsPayload []byte
|
||||||
contentsPayload, err = encodeContents(contents)
|
contentsPayload, err = encodeContents(contents)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to encode contents", "err", err)
|
p.Log.Error("failed to encode contents", "err", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -559,17 +559,17 @@ func (p *PortalProtocol) processOffer(target *enode.Node, resp []byte, request *
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
conncancel()
|
conncancel()
|
||||||
p.log.Error("failed to dial utp connection", "err", err)
|
p.Log.Error("failed to dial utp connection", "err", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
conncancel()
|
conncancel()
|
||||||
|
|
||||||
err = conn.SetWriteDeadline(time.Now().Add(defaultUTPWriteTimeout))
|
err = conn.SetWriteDeadline(time.Now().Add(defaultUTPWriteTimeout))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to set write deadline", "err", err)
|
p.Log.Error("failed to set write deadline", "err", err)
|
||||||
err = conn.Close()
|
err = conn.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to close utp connection", "err", err)
|
p.Log.Error("failed to close utp connection", "err", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -579,18 +579,18 @@ func (p *PortalProtocol) processOffer(target *enode.Node, resp []byte, request *
|
||||||
var written int
|
var written int
|
||||||
written, err = conn.Write(contentsPayload)
|
written, err = conn.Write(contentsPayload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to write to utp connection", "err", err)
|
p.Log.Error("failed to write to utp connection", "err", err)
|
||||||
err = conn.Close()
|
err = conn.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to close utp connection", "err", err)
|
p.Log.Error("failed to close utp connection", "err", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
p.log.Trace("Sent content response", "id", target.ID(), "contents", contents, "size", written)
|
p.Log.Trace("Sent content response", "id", target.ID(), "contents", contents, "size", written)
|
||||||
err = conn.Close()
|
err = conn.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to close utp connection", "err", err)
|
p.Log.Error("failed to close utp connection", "err", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|
@ -614,7 +614,7 @@ func (p *PortalProtocol) processContent(target *enode.Node, resp []byte) (byte,
|
||||||
return 0xff, nil, err
|
return 0xff, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
p.log.Trace("Received content response", "id", target.ID(), "content", content)
|
p.Log.Trace("Received content response", "id", target.ID(), "content", content)
|
||||||
p.setJustSeen(target)
|
p.setJustSeen(target)
|
||||||
return resp[1], content.Content, nil
|
return resp[1], content.Content, nil
|
||||||
case portalwire.ContentConnIdSelector:
|
case portalwire.ContentConnIdSelector:
|
||||||
|
|
@ -624,7 +624,7 @@ func (p *PortalProtocol) processContent(target *enode.Node, resp []byte) (byte,
|
||||||
return 0xff, nil, err
|
return 0xff, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
p.log.Trace("Received returned content response", "id", target.ID(), "connIdMsg", connIdMsg)
|
p.Log.Trace("Received returned content response", "id", target.ID(), "connIdMsg", connIdMsg)
|
||||||
p.setJustSeen(target)
|
p.setJustSeen(target)
|
||||||
connctx, conncancel := context.WithTimeout(p.closeCtx, defaultUTPConnectTimeout)
|
connctx, conncancel := context.WithTimeout(p.closeCtx, defaultUTPConnectTimeout)
|
||||||
laddr := p.utp.Addr().(*utp.Addr)
|
laddr := p.utp.Addr().(*utp.Addr)
|
||||||
|
|
@ -644,10 +644,10 @@ func (p *PortalProtocol) processContent(target *enode.Node, resp []byte) (byte,
|
||||||
// Read ALL the data from the connection until EOF and return it
|
// Read ALL the data from the connection until EOF and return it
|
||||||
data, err := io.ReadAll(conn)
|
data, err := io.ReadAll(conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to read from utp connection", "err", err)
|
p.Log.Error("failed to read from utp connection", "err", err)
|
||||||
return 0xff, nil, err
|
return 0xff, nil, err
|
||||||
}
|
}
|
||||||
p.log.Trace("Received content response", "id", target.ID(), "size", len(data), "data", data)
|
p.Log.Trace("Received content response", "id", target.ID(), "size", len(data), "data", data)
|
||||||
return resp[1], data, nil
|
return resp[1], data, nil
|
||||||
case portalwire.ContentEnrsSelector:
|
case portalwire.ContentEnrsSelector:
|
||||||
enrs := &portalwire.Enrs{}
|
enrs := &portalwire.Enrs{}
|
||||||
|
|
@ -657,7 +657,7 @@ func (p *PortalProtocol) processContent(target *enode.Node, resp []byte) (byte,
|
||||||
return 0xff, nil, err
|
return 0xff, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
p.log.Trace("Received content response", "id", target.ID(), "enrs", enrs)
|
p.Log.Trace("Received content response", "id", target.ID(), "enrs", enrs)
|
||||||
p.setJustSeen(target)
|
p.setJustSeen(target)
|
||||||
nodes := p.filterNodes(target, enrs.Enrs, nil)
|
nodes := p.filterNodes(target, enrs.Enrs, nil)
|
||||||
return resp[1], nodes, nil
|
return resp[1], nodes, nil
|
||||||
|
|
@ -702,19 +702,19 @@ func (p *PortalProtocol) filterNodes(target *enode.Node, enrs [][]byte, distance
|
||||||
record := &enr.Record{}
|
record := &enr.Record{}
|
||||||
err = rlp.DecodeBytes(b, record)
|
err = rlp.DecodeBytes(b, record)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("Invalid record in nodes response", "id", target.ID(), "err", err)
|
p.Log.Error("Invalid record in nodes response", "id", target.ID(), "err", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
n, err = p.verifyResponseNode(target, record, distances, seen)
|
n, err = p.verifyResponseNode(target, record, distances, seen)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("Invalid record in nodes response", "id", target.ID(), "err", err)
|
p.Log.Error("Invalid record in nodes response", "id", target.ID(), "err", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
verified++
|
verified++
|
||||||
nodes = append(nodes, n)
|
nodes = append(nodes, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
p.log.Trace("Received nodes response", "id", target.ID(), "total", len(enrs), "verified", verified, "nodes", nodes)
|
p.Log.Trace("Received nodes response", "id", target.ID(), "total", len(enrs), "verified", verified, "nodes", nodes)
|
||||||
return nodes
|
return nodes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -729,7 +729,7 @@ func (p *PortalProtocol) processPong(target *enode.Node, resp []byte) (*portalwi
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
p.log.Trace("Received pong response", "id", target.ID(), "pong", pong)
|
p.Log.Trace("Received pong response", "id", target.ID(), "pong", pong)
|
||||||
|
|
||||||
customPayload := &portalwire.PingPongCustomData{}
|
customPayload := &portalwire.PingPongCustomData{}
|
||||||
err = customPayload.UnmarshalSSZ(pong.CustomPayload)
|
err = customPayload.UnmarshalSSZ(pong.CustomPayload)
|
||||||
|
|
@ -738,7 +738,7 @@ func (p *PortalProtocol) processPong(target *enode.Node, resp []byte) (*portalwi
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
p.log.Trace("Received pong response", "id", target.ID(), "pong", pong, "customPayload", customPayload)
|
p.Log.Trace("Received pong response", "id", target.ID(), "pong", pong, "customPayload", customPayload)
|
||||||
p.setJustSeen(target)
|
p.setJustSeen(target)
|
||||||
|
|
||||||
p.radiusCache.Set([]byte(target.ID().String()), customPayload.Radius)
|
p.radiusCache.Set([]byte(target.ID().String()), customPayload.Radius)
|
||||||
|
|
@ -749,13 +749,13 @@ func (p *PortalProtocol) handleUtpTalkRequest(id enode.ID, addr *net.UDPAddr, ms
|
||||||
if n := p.DiscV5.getNode(id); n != nil {
|
if n := p.DiscV5.getNode(id); n != nil {
|
||||||
p.table.addSeenNode(wrapNode(n))
|
p.table.addSeenNode(wrapNode(n))
|
||||||
}
|
}
|
||||||
p.log.Trace("receive utp data", "addr", addr, "msg-length", len(msg))
|
p.Log.Trace("receive utp data", "addr", addr, "msg-length", len(msg))
|
||||||
p.packetRouter.ReceiveMessage(msg, addr)
|
p.packetRouter.ReceiveMessage(msg, addr)
|
||||||
return []byte("")
|
return []byte("")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PortalProtocol) handleTalkRequest(id enode.ID, addr *net.UDPAddr, msg []byte) []byte {
|
func (p *PortalProtocol) handleTalkRequest(id enode.ID, addr *net.UDPAddr, msg []byte) []byte {
|
||||||
p.log.Trace("handleTalkRequest", "id", id, "addr", addr)
|
p.Log.Trace("handleTalkRequest", "id", id, "addr", addr)
|
||||||
if n := p.DiscV5.getNode(id); n != nil {
|
if n := p.DiscV5.getNode(id); n != nil {
|
||||||
p.table.addSeenNode(wrapNode(n))
|
p.table.addSeenNode(wrapNode(n))
|
||||||
}
|
}
|
||||||
|
|
@ -767,14 +767,14 @@ func (p *PortalProtocol) handleTalkRequest(id enode.ID, addr *net.UDPAddr, msg [
|
||||||
pingRequest := &portalwire.Ping{}
|
pingRequest := &portalwire.Ping{}
|
||||||
err := pingRequest.UnmarshalSSZ(msg[1:])
|
err := pingRequest.UnmarshalSSZ(msg[1:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to unmarshal ping request", "err", err)
|
p.Log.Error("failed to unmarshal ping request", "err", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
p.log.Trace("received ping request", "protocol", p.protocolId, "source", id, "pingRequest", pingRequest)
|
p.Log.Trace("received ping request", "protocol", p.protocolId, "source", id, "pingRequest", pingRequest)
|
||||||
resp, err := p.handlePing(id, pingRequest)
|
resp, err := p.handlePing(id, pingRequest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to handle ping request", "err", err)
|
p.Log.Error("failed to handle ping request", "err", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -783,14 +783,14 @@ func (p *PortalProtocol) handleTalkRequest(id enode.ID, addr *net.UDPAddr, msg [
|
||||||
findNodesRequest := &portalwire.FindNodes{}
|
findNodesRequest := &portalwire.FindNodes{}
|
||||||
err := findNodesRequest.UnmarshalSSZ(msg[1:])
|
err := findNodesRequest.UnmarshalSSZ(msg[1:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to unmarshal find nodes request", "err", err)
|
p.Log.Error("failed to unmarshal find nodes request", "err", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
p.log.Trace("received find nodes request", "protocol", p.protocolId, "source", id, "findNodesRequest", findNodesRequest)
|
p.Log.Trace("received find nodes request", "protocol", p.protocolId, "source", id, "findNodesRequest", findNodesRequest)
|
||||||
resp, err := p.handleFindNodes(addr, findNodesRequest)
|
resp, err := p.handleFindNodes(addr, findNodesRequest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to handle find nodes request", "err", err)
|
p.Log.Error("failed to handle find nodes request", "err", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -799,14 +799,14 @@ func (p *PortalProtocol) handleTalkRequest(id enode.ID, addr *net.UDPAddr, msg [
|
||||||
findContentRequest := &portalwire.FindContent{}
|
findContentRequest := &portalwire.FindContent{}
|
||||||
err := findContentRequest.UnmarshalSSZ(msg[1:])
|
err := findContentRequest.UnmarshalSSZ(msg[1:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to unmarshal find content request", "err", err)
|
p.Log.Error("failed to unmarshal find content request", "err", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
p.log.Trace("received find content request", "protocol", p.protocolId, "source", id, "findContentRequest", findContentRequest)
|
p.Log.Trace("received find content request", "protocol", p.protocolId, "source", id, "findContentRequest", findContentRequest)
|
||||||
resp, err := p.handleFindContent(id, addr, findContentRequest)
|
resp, err := p.handleFindContent(id, addr, findContentRequest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to handle find content request", "err", err)
|
p.Log.Error("failed to handle find content request", "err", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -815,14 +815,14 @@ func (p *PortalProtocol) handleTalkRequest(id enode.ID, addr *net.UDPAddr, msg [
|
||||||
offerRequest := &portalwire.Offer{}
|
offerRequest := &portalwire.Offer{}
|
||||||
err := offerRequest.UnmarshalSSZ(msg[1:])
|
err := offerRequest.UnmarshalSSZ(msg[1:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to unmarshal offer request", "err", err)
|
p.Log.Error("failed to unmarshal offer request", "err", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
p.log.Trace("received offer request", "protocol", p.protocolId, "source", id, "offerRequest", offerRequest)
|
p.Log.Trace("received offer request", "protocol", p.protocolId, "source", id, "offerRequest", offerRequest)
|
||||||
resp, err := p.handleOffer(id, addr, offerRequest)
|
resp, err := p.handleOffer(id, addr, offerRequest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to handle offer request", "err", err)
|
p.Log.Error("failed to handle offer request", "err", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -860,7 +860,7 @@ func (p *PortalProtocol) handlePing(id enode.ID, ping *portalwire.Ping) ([]byte,
|
||||||
CustomPayload: pongCustomPayloadBytes,
|
CustomPayload: pongCustomPayloadBytes,
|
||||||
}
|
}
|
||||||
|
|
||||||
p.log.Trace("Sending pong response", "protocol", p.protocolId, "source", id, "pong", pong)
|
p.Log.Trace("Sending pong response", "protocol", p.protocolId, "source", id, "pong", pong)
|
||||||
pongBytes, err := pong.MarshalSSZ()
|
pongBytes, err := pong.MarshalSSZ()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -893,7 +893,7 @@ func (p *PortalProtocol) handleFindNodes(fromAddr *net.UDPAddr, request *portalw
|
||||||
Enrs: enrs,
|
Enrs: enrs,
|
||||||
}
|
}
|
||||||
|
|
||||||
p.log.Trace("Sending nodes response", "protocol", p.protocolId, "source", fromAddr, "nodes", nodesMsg)
|
p.Log.Trace("Sending nodes response", "protocol", p.protocolId, "source", fromAddr, "nodes", nodesMsg)
|
||||||
nodesMsgBytes, err := nodesMsg.MarshalSSZ()
|
nodesMsgBytes, err := nodesMsg.MarshalSSZ()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -942,7 +942,7 @@ func (p *PortalProtocol) handleFindContent(id enode.ID, addr *net.UDPAddr, reque
|
||||||
Enrs: enrs,
|
Enrs: enrs,
|
||||||
}
|
}
|
||||||
|
|
||||||
p.log.Trace("Sending enrs content response", "protocol", p.protocolId, "source", addr, "enrs", enrsMsg)
|
p.Log.Trace("Sending enrs content response", "protocol", p.protocolId, "source", addr, "enrs", enrsMsg)
|
||||||
var enrsMsgBytes []byte
|
var enrsMsgBytes []byte
|
||||||
enrsMsgBytes, err = enrsMsg.MarshalSSZ()
|
enrsMsgBytes, err = enrsMsg.MarshalSSZ()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -963,7 +963,7 @@ func (p *PortalProtocol) handleFindContent(id enode.ID, addr *net.UDPAddr, reque
|
||||||
Content: content,
|
Content: content,
|
||||||
}
|
}
|
||||||
|
|
||||||
p.log.Trace("Sending raw content response", "protocol", p.protocolId, "source", addr, "content", rawContentMsg)
|
p.Log.Trace("Sending raw content response", "protocol", p.protocolId, "source", addr, "content", rawContentMsg)
|
||||||
|
|
||||||
var rawContentMsgBytes []byte
|
var rawContentMsgBytes []byte
|
||||||
rawContentMsgBytes, err = rawContentMsg.MarshalSSZ()
|
rawContentMsgBytes, err = rawContentMsg.MarshalSSZ()
|
||||||
|
|
@ -995,7 +995,7 @@ func (p *PortalProtocol) handleFindContent(id enode.ID, addr *net.UDPAddr, reque
|
||||||
var conn *utp.Conn
|
var conn *utp.Conn
|
||||||
conn, err = p.utp.AcceptUTPContext(ctx, connIdSend)
|
conn, err = p.utp.AcceptUTPContext(ctx, connIdSend)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to accept utp connection", "connId", connIdSend, "err", err)
|
p.Log.Error("failed to accept utp connection", "connId", connIdSend, "err", err)
|
||||||
cancel()
|
cancel()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -1003,10 +1003,10 @@ func (p *PortalProtocol) handleFindContent(id enode.ID, addr *net.UDPAddr, reque
|
||||||
|
|
||||||
err = conn.SetWriteDeadline(time.Now().Add(defaultUTPWriteTimeout))
|
err = conn.SetWriteDeadline(time.Now().Add(defaultUTPWriteTimeout))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to set write deadline", "err", err)
|
p.Log.Error("failed to set write deadline", "err", err)
|
||||||
err = conn.Close()
|
err = conn.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to close utp connection", "err", err)
|
p.Log.Error("failed to close utp connection", "err", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|
@ -1015,10 +1015,10 @@ func (p *PortalProtocol) handleFindContent(id enode.ID, addr *net.UDPAddr, reque
|
||||||
var n int
|
var n int
|
||||||
n, err = conn.Write(content)
|
n, err = conn.Write(content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to write content to utp connection", "err", err)
|
p.Log.Error("failed to write content to utp connection", "err", err)
|
||||||
err = conn.Close()
|
err = conn.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to close utp connection", "err", err)
|
p.Log.Error("failed to close utp connection", "err", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|
@ -1026,11 +1026,11 @@ func (p *PortalProtocol) handleFindContent(id enode.ID, addr *net.UDPAddr, reque
|
||||||
|
|
||||||
err = conn.Close()
|
err = conn.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to close utp connection", "err", err)
|
p.Log.Error("failed to close utp connection", "err", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
p.log.Trace("wrote content size to utp connection", "n", n)
|
p.Log.Trace("wrote content size to utp connection", "n", n)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1042,7 +1042,7 @@ func (p *PortalProtocol) handleFindContent(id enode.ID, addr *net.UDPAddr, reque
|
||||||
Id: idBuffer,
|
Id: idBuffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
p.log.Trace("Sending connection id content response", "protocol", p.protocolId, "source", addr, "connId", connIdMsg)
|
p.Log.Trace("Sending connection id content response", "protocol", p.protocolId, "source", addr, "connId", connIdMsg)
|
||||||
var connIdMsgBytes []byte
|
var connIdMsgBytes []byte
|
||||||
connIdMsgBytes, err = connIdMsg.MarshalSSZ()
|
connIdMsgBytes, err = connIdMsg.MarshalSSZ()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -1070,7 +1070,7 @@ func (p *PortalProtocol) handleOffer(id enode.ID, addr *net.UDPAddr, request *po
|
||||||
ContentKeys: contentKeyBitlist,
|
ContentKeys: contentKeyBitlist,
|
||||||
}
|
}
|
||||||
|
|
||||||
p.log.Trace("Sending accept response", "protocol", p.protocolId, "source", addr, "accept", acceptMsg)
|
p.Log.Trace("Sending accept response", "protocol", p.protocolId, "source", addr, "accept", acceptMsg)
|
||||||
var acceptMsgBytes []byte
|
var acceptMsgBytes []byte
|
||||||
acceptMsgBytes, err = acceptMsg.MarshalSSZ()
|
acceptMsgBytes, err = acceptMsg.MarshalSSZ()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -1115,7 +1115,7 @@ func (p *PortalProtocol) handleOffer(id enode.ID, addr *net.UDPAddr, request *po
|
||||||
var conn *utp.Conn
|
var conn *utp.Conn
|
||||||
conn, err = p.utp.AcceptUTPContext(ctx, connIdSend)
|
conn, err = p.utp.AcceptUTPContext(ctx, connIdSend)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to accept utp connection", "connId", connIdSend, "err", err)
|
p.Log.Error("failed to accept utp connection", "connId", connIdSend, "err", err)
|
||||||
cancel()
|
cancel()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -1123,21 +1123,21 @@ func (p *PortalProtocol) handleOffer(id enode.ID, addr *net.UDPAddr, request *po
|
||||||
|
|
||||||
err = conn.SetReadDeadline(time.Now().Add(defaultUTPReadTimeout))
|
err = conn.SetReadDeadline(time.Now().Add(defaultUTPReadTimeout))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to set read deadline", "err", err)
|
p.Log.Error("failed to set read deadline", "err", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Read ALL the data from the connection until EOF and return it
|
// Read ALL the data from the connection until EOF and return it
|
||||||
var data []byte
|
var data []byte
|
||||||
data, err = io.ReadAll(conn)
|
data, err = io.ReadAll(conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to read from utp connection", "err", err)
|
p.Log.Error("failed to read from utp connection", "err", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
p.log.Trace("Received offer content response", "id", id, "size", len(data), "data", data)
|
p.Log.Trace("Received offer content response", "id", id, "size", len(data), "data", data)
|
||||||
|
|
||||||
err = p.handleOfferedContents(id, contentKeys, data)
|
err = p.handleOfferedContents(id, contentKeys, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to handle offered Contents", "err", err)
|
p.Log.Error("failed to handle offered Contents", "err", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1156,7 +1156,7 @@ func (p *PortalProtocol) handleOffer(id enode.ID, addr *net.UDPAddr, request *po
|
||||||
ContentKeys: []byte(contentKeyBitlist),
|
ContentKeys: []byte(contentKeyBitlist),
|
||||||
}
|
}
|
||||||
|
|
||||||
p.log.Trace("Sending accept response", "protocol", p.protocolId, "source", addr, "accept", acceptMsg)
|
p.Log.Trace("Sending accept response", "protocol", p.protocolId, "source", addr, "accept", acceptMsg)
|
||||||
var acceptMsgBytes []byte
|
var acceptMsgBytes []byte
|
||||||
acceptMsgBytes, err = acceptMsg.MarshalSSZ()
|
acceptMsgBytes, err = acceptMsg.MarshalSSZ()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -1295,10 +1295,10 @@ func (p *PortalProtocol) offerWorker() {
|
||||||
case <-p.closeCtx.Done():
|
case <-p.closeCtx.Done():
|
||||||
return
|
return
|
||||||
case offerRequestWithNode := <-p.offerQueue:
|
case offerRequestWithNode := <-p.offerQueue:
|
||||||
p.log.Trace("offerWorker", "offerRequestWithNode", offerRequestWithNode)
|
p.Log.Trace("offerWorker", "offerRequestWithNode", offerRequestWithNode)
|
||||||
_, err := p.offer(offerRequestWithNode.Node, offerRequestWithNode.Request)
|
_, err := p.offer(offerRequestWithNode.Node, offerRequestWithNode.Request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to offer", "err", err)
|
p.Log.Error("failed to offer", "err", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1310,7 +1310,7 @@ func (p *PortalProtocol) truncateNodes(nodes []*enode.Node, maxSize int, enrOver
|
||||||
for _, n := range nodes {
|
for _, n := range nodes {
|
||||||
enrBytes, err := rlp.EncodeToBytes(n.Record())
|
enrBytes, err := rlp.EncodeToBytes(n.Record())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.log.Error("failed to encode n", "err", err)
|
p.Log.Error("failed to encode n", "err", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1619,21 +1619,21 @@ func (p *PortalProtocol) InRange(contentId []byte) bool {
|
||||||
|
|
||||||
func (p *PortalProtocol) Get(contentKey []byte, contentId []byte) ([]byte, error) {
|
func (p *PortalProtocol) Get(contentKey []byte, contentId []byte) ([]byte, error) {
|
||||||
content, err := p.storage.Get(contentKey, contentId)
|
content, err := p.storage.Get(contentKey, contentId)
|
||||||
p.log.Trace("get local storage", "contentId", hexutil.Encode(contentId), "content", hexutil.Encode(content), "err", err)
|
p.Log.Trace("get local storage", "contentId", hexutil.Encode(contentId), "content", hexutil.Encode(content), "err", err)
|
||||||
return content, err
|
return content, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PortalProtocol) Put(contentKey []byte, contentId []byte, content []byte) error {
|
func (p *PortalProtocol) Put(contentKey []byte, contentId []byte, content []byte) error {
|
||||||
err := p.storage.Put(contentKey, contentId, content)
|
err := p.storage.Put(contentKey, contentId, content)
|
||||||
p.log.Trace("put local storage", "contentId", hexutil.Encode(contentId), "content", hexutil.Encode(content), "err", err)
|
p.Log.Trace("put local storage", "contentId", hexutil.Encode(contentId), "content", hexutil.Encode(content), "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PortalProtocol) GetContent() <-chan *ContentElement {
|
func (p *PortalProtocol) GetContent() chan *ContentElement {
|
||||||
return p.contentQueue
|
return p.contentQueue
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PortalProtocol) NeighborhoodGossip(srcNodeId *enode.ID, contentKeys [][]byte, content [][]byte) (int, error) {
|
func (p *PortalProtocol) Gossip(srcNodeId *enode.ID, contentKeys [][]byte, content [][]byte) (int, error) {
|
||||||
if len(content) == 0 {
|
if len(content) == 0 {
|
||||||
return 0, errors.New("empty content")
|
return 0, errors.New("empty content")
|
||||||
}
|
}
|
||||||
|
|
@ -1652,23 +1652,9 @@ func (p *PortalProtocol) NeighborhoodGossip(srcNodeId *enode.ID, contentKeys [][
|
||||||
return 0, ErrNilContentKey
|
return 0, ErrNilContentKey
|
||||||
}
|
}
|
||||||
|
|
||||||
// For selecting the closest nodes to whom to gossip the content a mixed
|
maxClosestNodes := 4
|
||||||
// approach is taken:
|
maxFartherNodes := 4
|
||||||
// 1. Select the closest neighbours in the routing table
|
closestLocalNodes := p.findNodesCloseToContent(contentId, 32)
|
||||||
// 2. Check if the radius is known for these these nodes and whether they are
|
|
||||||
// in range of the content to be offered.
|
|
||||||
// 3. If more than n (= 8) nodes are in range, offer these nodes the content
|
|
||||||
// (max nodes set at 8).
|
|
||||||
// 4. If less than n nodes are in range, do a node lookup, and offer the nodes
|
|
||||||
// returned from the lookup the content (max nodes set at 8)
|
|
||||||
//
|
|
||||||
// This should give a bigger rate of success and avoid the data being stopped
|
|
||||||
// in its propagation than when looking only for nodes in the own routing
|
|
||||||
// table, but at the same time avoid unnecessary node lookups.
|
|
||||||
// It might still cause issues in data getting propagated in a wider id range.
|
|
||||||
maxGossipNodes := 8
|
|
||||||
|
|
||||||
closestLocalNodes := p.findNodesCloseToContent(contentId, 16)
|
|
||||||
|
|
||||||
gossipNodes := make([]*enode.Node, 0)
|
gossipNodes := make([]*enode.Node, 0)
|
||||||
for _, n := range closestLocalNodes {
|
for _, n := range closestLocalNodes {
|
||||||
|
|
@ -1689,74 +1675,22 @@ func (p *PortalProtocol) NeighborhoodGossip(srcNodeId *enode.ID, contentKeys [][
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(gossipNodes) >= maxGossipNodes {
|
if len(gossipNodes) == 0 {
|
||||||
numberOfGossipedNodes := min(len(gossipNodes), maxGossipNodes)
|
return 0, nil
|
||||||
for _, n := range gossipNodes[:numberOfGossipedNodes] {
|
}
|
||||||
transientOfferRequest := &TransientOfferRequest{
|
|
||||||
Contents: contentList,
|
|
||||||
}
|
|
||||||
|
|
||||||
offerRequest := &OfferRequest{
|
var finalGossipNodes []*enode.Node
|
||||||
Kind: TransientOfferRequestKind,
|
if len(gossipNodes) > maxClosestNodes {
|
||||||
Request: transientOfferRequest,
|
fartherNodes := gossipNodes[maxClosestNodes:]
|
||||||
}
|
rand.Shuffle(len(fartherNodes), func(i, j int) {
|
||||||
|
fartherNodes[i], fartherNodes[j] = fartherNodes[j], fartherNodes[i]
|
||||||
offerRequestWithNode := &OfferRequestWithNode{
|
})
|
||||||
Node: n,
|
finalGossipNodes = append(gossipNodes[:maxClosestNodes], fartherNodes[:min(maxFartherNodes, len(fartherNodes))]...)
|
||||||
Request: offerRequest,
|
|
||||||
}
|
|
||||||
p.offerQueue <- offerRequestWithNode
|
|
||||||
}
|
|
||||||
|
|
||||||
return numberOfGossipedNodes, nil
|
|
||||||
} else {
|
} else {
|
||||||
closestNodes := p.Lookup(enode.ID(contentId))
|
finalGossipNodes = gossipNodes
|
||||||
numberOfGossipedNodes := min(len(closestNodes), maxGossipNodes)
|
|
||||||
// Note: opportunistically not checking if the radius of the node is known
|
|
||||||
// and thus if the node is in radius with the content. Reason is, these
|
|
||||||
// should really be the closest nodes in the DHT, and thus are most likely
|
|
||||||
// going to be in range of the requested content.
|
|
||||||
for _, n := range closestNodes[:numberOfGossipedNodes] {
|
|
||||||
transientOfferRequest := &TransientOfferRequest{
|
|
||||||
Contents: contentList,
|
|
||||||
}
|
|
||||||
|
|
||||||
offerRequest := &OfferRequest{
|
|
||||||
Kind: TransientOfferRequestKind,
|
|
||||||
Request: transientOfferRequest,
|
|
||||||
}
|
|
||||||
|
|
||||||
offerRequestWithNode := &OfferRequestWithNode{
|
|
||||||
Node: n,
|
|
||||||
Request: offerRequest,
|
|
||||||
}
|
|
||||||
p.offerQueue <- offerRequestWithNode
|
|
||||||
}
|
|
||||||
|
|
||||||
return numberOfGossipedNodes, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PortalProtocol) RandomGossip(srcNodeId *enode.ID, contentKeys [][]byte, content [][]byte) (int, error) {
|
|
||||||
if len(content) == 0 {
|
|
||||||
return 0, errors.New("empty content")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
contentList := make([]*ContentEntry, 0, portalwire.ContentKeysLimit)
|
for _, n := range finalGossipNodes {
|
||||||
for i := 0; i < len(content); i++ {
|
|
||||||
contentEntry := &ContentEntry{
|
|
||||||
ContentKey: contentKeys[i],
|
|
||||||
Content: content[i],
|
|
||||||
}
|
|
||||||
contentList = append(contentList, contentEntry)
|
|
||||||
}
|
|
||||||
|
|
||||||
maxGossipNodes := 4
|
|
||||||
nodes := RandomNodes(p.table, maxGossipNodes, func(node *enode.Node) bool {
|
|
||||||
return srcNodeId == nil || node.ID() != *srcNodeId
|
|
||||||
})
|
|
||||||
|
|
||||||
for _, n := range nodes {
|
|
||||||
transientOfferRequest := &TransientOfferRequest{
|
transientOfferRequest := &TransientOfferRequest{
|
||||||
Contents: contentList,
|
Contents: contentList,
|
||||||
}
|
}
|
||||||
|
|
@ -1773,7 +1707,7 @@ func (p *PortalProtocol) RandomGossip(srcNodeId *enode.ID, contentKeys [][]byte,
|
||||||
p.offerQueue <- offerRequestWithNode
|
p.offerQueue <- offerRequestWithNode
|
||||||
}
|
}
|
||||||
|
|
||||||
return len(nodes), nil
|
return len(finalGossipNodes), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PortalProtocol) Distance(a, b enode.ID) enode.ID {
|
func (p *PortalProtocol) Distance(a, b enode.ID) enode.ID {
|
||||||
|
|
@ -1781,7 +1715,7 @@ func (p *PortalProtocol) Distance(a, b enode.ID) enode.ID {
|
||||||
for i := range a {
|
for i := range a {
|
||||||
res[i] = a[i] ^ b[i]
|
res[i] = a[i] ^ b[i]
|
||||||
}
|
}
|
||||||
return enode.ID(res)
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func inRange(nodeId enode.ID, nodeRadius *uint256.Int, contentId []byte) bool {
|
func inRange(nodeId enode.ID, nodeRadius *uint256.Int, contentId []byte) bool {
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/portalnetwork/storage"
|
||||||
"github.com/prysmaticlabs/go-bitfield"
|
"github.com/prysmaticlabs/go-bitfield"
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
|
|
||||||
|
|
@ -23,22 +24,6 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MockStorage struct {
|
|
||||||
db map[string][]byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MockStorage) Get(contentKey []byte, contentId []byte) ([]byte, error) {
|
|
||||||
if content, ok := m.db[string(contentId)]; ok {
|
|
||||||
return content, nil
|
|
||||||
}
|
|
||||||
return nil, ContentNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MockStorage) Put(contentKey []byte, contentId []byte, content []byte) error {
|
|
||||||
m.db[string(contentId)] = content
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func setupLocalPortalNode(addr string, bootNodes []*enode.Node) (*PortalProtocol, error) {
|
func setupLocalPortalNode(addr string, bootNodes []*enode.Node) (*PortalProtocol, error) {
|
||||||
conf := DefaultPortalProtocolConfig()
|
conf := DefaultPortalProtocolConfig()
|
||||||
if addr != "" {
|
if addr != "" {
|
||||||
|
|
@ -101,7 +86,7 @@ func setupLocalPortalNode(addr string, bootNodes []*enode.Node) (*PortalProtocol
|
||||||
}
|
}
|
||||||
|
|
||||||
contentQueue := make(chan *ContentElement, 50)
|
contentQueue := make(chan *ContentElement, 50)
|
||||||
portalProtocol, err := NewPortalProtocol(conf, string(portalwire.HistoryNetwork), privKey, conn, localNode, discV5, &MockStorage{db: make(map[string][]byte)}, contentQueue)
|
portalProtocol, err := NewPortalProtocol(conf, string(portalwire.HistoryNetwork), privKey, conn, localNode, discV5, &storage.MockStorage{Db: make(map[string][]byte)}, contentQueue)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -112,19 +97,19 @@ func setupLocalPortalNode(addr string, bootNodes []*enode.Node) (*PortalProtocol
|
||||||
func TestPortalWireProtocolUdp(t *testing.T) {
|
func TestPortalWireProtocolUdp(t *testing.T) {
|
||||||
node1, err := setupLocalPortalNode(":8777", nil)
|
node1, err := setupLocalPortalNode(":8777", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
node1.log = testlog.Logger(t, log.LvlTrace)
|
node1.Log = testlog.Logger(t, log.LvlTrace)
|
||||||
err = node1.Start()
|
err = node1.Start()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
node2, err := setupLocalPortalNode(":8778", []*enode.Node{node1.localNode.Node()})
|
node2, err := setupLocalPortalNode(":8778", []*enode.Node{node1.localNode.Node()})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
node2.log = testlog.Logger(t, log.LvlTrace)
|
node2.Log = testlog.Logger(t, log.LvlTrace)
|
||||||
err = node2.Start()
|
err = node2.Start()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
node3, err := setupLocalPortalNode(":8779", []*enode.Node{node1.localNode.Node()})
|
node3, err := setupLocalPortalNode(":8779", []*enode.Node{node1.localNode.Node()})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
node3.log = testlog.Logger(t, log.LvlTrace)
|
node3.Log = testlog.Logger(t, log.LvlTrace)
|
||||||
err = node3.Start()
|
err = node3.Start()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
time.Sleep(10 * time.Second)
|
time.Sleep(10 * time.Second)
|
||||||
|
|
@ -254,7 +239,7 @@ func TestPortalWireProtocolUdp(t *testing.T) {
|
||||||
func TestPortalWireProtocol(t *testing.T) {
|
func TestPortalWireProtocol(t *testing.T) {
|
||||||
node1, err := setupLocalPortalNode(":7777", nil)
|
node1, err := setupLocalPortalNode(":7777", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
node1.log = testlog.Logger(t, log.LevelDebug)
|
node1.Log = testlog.Logger(t, log.LevelDebug)
|
||||||
err = node1.Start()
|
err = node1.Start()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
fmt.Println(node1.localNode.Node().String())
|
fmt.Println(node1.localNode.Node().String())
|
||||||
|
|
@ -263,7 +248,7 @@ func TestPortalWireProtocol(t *testing.T) {
|
||||||
|
|
||||||
node2, err := setupLocalPortalNode(":7778", []*enode.Node{node1.localNode.Node()})
|
node2, err := setupLocalPortalNode(":7778", []*enode.Node{node1.localNode.Node()})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
node2.log = testlog.Logger(t, log.LevelDebug)
|
node2.Log = testlog.Logger(t, log.LevelDebug)
|
||||||
err = node2.Start()
|
err = node2.Start()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
fmt.Println(node2.localNode.Node().String())
|
fmt.Println(node2.localNode.Node().String())
|
||||||
|
|
@ -272,7 +257,7 @@ func TestPortalWireProtocol(t *testing.T) {
|
||||||
|
|
||||||
node3, err := setupLocalPortalNode(":7779", []*enode.Node{node1.localNode.Node()})
|
node3, err := setupLocalPortalNode(":7779", []*enode.Node{node1.localNode.Node()})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
node3.log = testlog.Logger(t, log.LevelDebug)
|
node3.Log = testlog.Logger(t, log.LevelDebug)
|
||||||
err = node3.Start()
|
err = node3.Start()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
fmt.Println(node3.localNode.Node().String())
|
fmt.Println(node3.localNode.Node().String())
|
||||||
|
|
@ -365,7 +350,7 @@ func TestPortalWireProtocol(t *testing.T) {
|
||||||
testGossipContentKeys := [][]byte{[]byte("test_gossip_content_keys"), []byte("test_gossip_content_keys2")}
|
testGossipContentKeys := [][]byte{[]byte("test_gossip_content_keys"), []byte("test_gossip_content_keys2")}
|
||||||
testGossipContent := [][]byte{[]byte("test_gossip_content"), []byte("test_gossip_content2")}
|
testGossipContent := [][]byte{[]byte("test_gossip_content"), []byte("test_gossip_content2")}
|
||||||
id := node1.Self().ID()
|
id := node1.Self().ID()
|
||||||
gossip, err := node1.NeighborhoodGossip(&id, testGossipContentKeys, testGossipContent)
|
gossip, err := node1.Gossip(&id, testGossipContentKeys, testGossipContent)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, 2, gossip)
|
assert.Equal(t, 2, gossip)
|
||||||
|
|
||||||
|
|
@ -383,26 +368,6 @@ func TestPortalWireProtocol(t *testing.T) {
|
||||||
assert.Equal(t, testGossipContentKeys[1], contentElement.ContentKeys[1])
|
assert.Equal(t, testGossipContentKeys[1], contentElement.ContentKeys[1])
|
||||||
assert.Equal(t, testGossipContent[1], contentElement.Contents[1])
|
assert.Equal(t, testGossipContent[1], contentElement.Contents[1])
|
||||||
|
|
||||||
testRandGossipContentKeys := [][]byte{[]byte("test_rand_gossip_content_keys"), []byte("test_rand_gossip_content_keys2")}
|
|
||||||
testRandGossipContent := [][]byte{[]byte("test_rand_gossip_content"), []byte("test_rand_gossip_content2")}
|
|
||||||
randGossip, err := node1.RandomGossip(&id, testRandGossipContentKeys, testRandGossipContent)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, 2, randGossip)
|
|
||||||
|
|
||||||
contentElement = <-node2.contentQueue
|
|
||||||
assert.Equal(t, node1.localNode.Node().ID(), contentElement.Node)
|
|
||||||
assert.Equal(t, testRandGossipContentKeys[0], contentElement.ContentKeys[0])
|
|
||||||
assert.Equal(t, testRandGossipContent[0], contentElement.Contents[0])
|
|
||||||
assert.Equal(t, testRandGossipContentKeys[1], contentElement.ContentKeys[1])
|
|
||||||
assert.Equal(t, testRandGossipContent[1], contentElement.Contents[1])
|
|
||||||
|
|
||||||
contentElement = <-node3.contentQueue
|
|
||||||
assert.Equal(t, node1.localNode.Node().ID(), contentElement.Node)
|
|
||||||
assert.Equal(t, testRandGossipContentKeys[0], contentElement.ContentKeys[0])
|
|
||||||
assert.Equal(t, testRandGossipContent[0], contentElement.Contents[0])
|
|
||||||
assert.Equal(t, testRandGossipContentKeys[1], contentElement.ContentKeys[1])
|
|
||||||
assert.Equal(t, testRandGossipContent[1], contentElement.Contents[1])
|
|
||||||
|
|
||||||
node1.Stop()
|
node1.Stop()
|
||||||
node2.Stop()
|
node2.Stop()
|
||||||
node3.Stop()
|
node3.Stop()
|
||||||
|
|
@ -428,21 +393,21 @@ func TestCancel(t *testing.T) {
|
||||||
func TestContentLookup(t *testing.T) {
|
func TestContentLookup(t *testing.T) {
|
||||||
node1, err := setupLocalPortalNode(":17777", nil)
|
node1, err := setupLocalPortalNode(":17777", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
node1.log = testlog.Logger(t, log.LvlTrace)
|
node1.Log = testlog.Logger(t, log.LvlTrace)
|
||||||
err = node1.Start()
|
err = node1.Start()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
fmt.Println(node1.localNode.Node().String())
|
fmt.Println(node1.localNode.Node().String())
|
||||||
|
|
||||||
node2, err := setupLocalPortalNode(":17778", []*enode.Node{node1.localNode.Node()})
|
node2, err := setupLocalPortalNode(":17778", []*enode.Node{node1.localNode.Node()})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
node2.log = testlog.Logger(t, log.LvlTrace)
|
node2.Log = testlog.Logger(t, log.LvlTrace)
|
||||||
err = node2.Start()
|
err = node2.Start()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
fmt.Println(node2.localNode.Node().String())
|
fmt.Println(node2.localNode.Node().String())
|
||||||
|
|
||||||
node3, err := setupLocalPortalNode(":17779", []*enode.Node{node1.localNode.Node()})
|
node3, err := setupLocalPortalNode(":17779", []*enode.Node{node1.localNode.Node()})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
node3.log = testlog.Logger(t, log.LvlTrace)
|
node3.Log = testlog.Logger(t, log.LvlTrace)
|
||||||
err = node3.Start()
|
err = node3.Start()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
fmt.Println(node3.localNode.Node().String())
|
fmt.Println(node3.localNode.Node().String())
|
||||||
|
|
@ -468,19 +433,19 @@ func TestContentLookup(t *testing.T) {
|
||||||
func TestTraceContentLookup(t *testing.T) {
|
func TestTraceContentLookup(t *testing.T) {
|
||||||
node1, err := setupLocalPortalNode(":17787", nil)
|
node1, err := setupLocalPortalNode(":17787", nil)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
node1.log = testlog.Logger(t, log.LvlTrace)
|
node1.Log = testlog.Logger(t, log.LvlTrace)
|
||||||
err = node1.Start()
|
err = node1.Start()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
node2, err := setupLocalPortalNode(":17788", []*enode.Node{node1.localNode.Node()})
|
node2, err := setupLocalPortalNode(":17788", []*enode.Node{node1.localNode.Node()})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
node2.log = testlog.Logger(t, log.LvlTrace)
|
node2.Log = testlog.Logger(t, log.LvlTrace)
|
||||||
err = node2.Start()
|
err = node2.Start()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
node3, err := setupLocalPortalNode(":17789", []*enode.Node{node2.localNode.Node()})
|
node3, err := setupLocalPortalNode(":17789", []*enode.Node{node2.localNode.Node()})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
node3.log = testlog.Logger(t, log.LvlTrace)
|
node3.Log = testlog.Logger(t, log.LvlTrace)
|
||||||
err = node3.Start()
|
err = node3.Start()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,18 @@ package beacon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
"github.com/ethereum/go-ethereum/portalnetwork/storage"
|
"github.com/ethereum/go-ethereum/portalnetwork/storage"
|
||||||
ssz "github.com/ferranbt/fastssz"
|
ssz "github.com/ferranbt/fastssz"
|
||||||
"github.com/protolambda/zrnt/eth2/beacon/capella"
|
"github.com/protolambda/zrnt/eth2/beacon/capella"
|
||||||
"github.com/protolambda/zrnt/eth2/beacon/common"
|
"github.com/protolambda/zrnt/eth2/beacon/common"
|
||||||
|
"github.com/protolambda/zrnt/eth2/configs"
|
||||||
"github.com/protolambda/ztyp/codec"
|
"github.com/protolambda/ztyp/codec"
|
||||||
"github.com/protolambda/ztyp/tree"
|
"github.com/protolambda/ztyp/tree"
|
||||||
)
|
)
|
||||||
|
|
@ -23,8 +28,38 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
type BeaconNetwork struct {
|
type BeaconNetwork struct {
|
||||||
PortalProtocol *discover.PortalProtocol
|
portalProtocol *discover.PortalProtocol
|
||||||
Spec *common.Spec
|
spec *common.Spec
|
||||||
|
log log.Logger
|
||||||
|
closeCtx context.Context
|
||||||
|
closeFunc context.CancelFunc
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBeaconNetwork(portalProtocol *discover.PortalProtocol) *BeaconNetwork {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
|
||||||
|
return &BeaconNetwork{
|
||||||
|
portalProtocol: portalProtocol,
|
||||||
|
spec: configs.Mainnet,
|
||||||
|
closeCtx: ctx,
|
||||||
|
closeFunc: cancel,
|
||||||
|
log: log.New("sub-protocol", "beacon"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bn *BeaconNetwork) Start() error {
|
||||||
|
err := bn.portalProtocol.Start()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
go bn.processContentLoop(bn.closeCtx)
|
||||||
|
bn.log.Debug("beacon network start successfully")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bn *BeaconNetwork) Stop() {
|
||||||
|
bn.closeFunc()
|
||||||
|
bn.portalProtocol.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bn *BeaconNetwork) GetUpdates(firstPeriod, count uint64) ([]*capella.LightClientUpdate, error) {
|
func (bn *BeaconNetwork) GetUpdates(firstPeriod, count uint64) ([]*capella.LightClientUpdate, error) {
|
||||||
|
|
@ -39,7 +74,7 @@ func (bn *BeaconNetwork) GetUpdates(firstPeriod, count uint64) ([]*capella.Light
|
||||||
}
|
}
|
||||||
|
|
||||||
var lightClientUpdateRange LightClientUpdateRange = make([]ForkedLightClientUpdate, 0)
|
var lightClientUpdateRange LightClientUpdateRange = make([]ForkedLightClientUpdate, 0)
|
||||||
err = lightClientUpdateRange.Deserialize(bn.Spec, codec.NewDecodingReader(bytes.NewReader(lightClientUpdateRangeContent), uint64(len(lightClientUpdateRangeContent))))
|
err = lightClientUpdateRange.Deserialize(bn.spec, codec.NewDecodingReader(bytes.NewReader(lightClientUpdateRangeContent), uint64(len(lightClientUpdateRangeContent))))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -65,7 +100,7 @@ func (bn *BeaconNetwork) GetCheckpointData(checkpointHash tree.Root) (*capella.L
|
||||||
}
|
}
|
||||||
|
|
||||||
var forkedLightClientBootstrap ForkedLightClientBootstrap
|
var forkedLightClientBootstrap ForkedLightClientBootstrap
|
||||||
err = forkedLightClientBootstrap.Deserialize(bn.Spec, codec.NewDecodingReader(bytes.NewReader(bootstrapValue), uint64(len(bootstrapValue))))
|
err = forkedLightClientBootstrap.Deserialize(bn.spec, codec.NewDecodingReader(bytes.NewReader(bootstrapValue), uint64(len(bootstrapValue))))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -88,7 +123,7 @@ func (bn *BeaconNetwork) GetFinalityUpdate(finalizedSlot uint64) (*capella.Light
|
||||||
}
|
}
|
||||||
|
|
||||||
var forkedLightClientFinalityUpdate ForkedLightClientFinalityUpdate
|
var forkedLightClientFinalityUpdate ForkedLightClientFinalityUpdate
|
||||||
err = forkedLightClientFinalityUpdate.Deserialize(bn.Spec, codec.NewDecodingReader(bytes.NewReader(finalityUpdateValue), uint64(len(finalityUpdateValue))))
|
err = forkedLightClientFinalityUpdate.Deserialize(bn.spec, codec.NewDecodingReader(bytes.NewReader(finalityUpdateValue), uint64(len(finalityUpdateValue))))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -111,7 +146,7 @@ func (bn *BeaconNetwork) GetOptimisticUpdate(optimisticSlot uint64) (*capella.Li
|
||||||
}
|
}
|
||||||
|
|
||||||
var forkedLightClientOptimisticUpdate ForkedLightClientOptimisticUpdate
|
var forkedLightClientOptimisticUpdate ForkedLightClientOptimisticUpdate
|
||||||
err = forkedLightClientOptimisticUpdate.Deserialize(bn.Spec, codec.NewDecodingReader(bytes.NewReader(optimisticUpdateValue), uint64(len(optimisticUpdateValue))))
|
err = forkedLightClientOptimisticUpdate.Deserialize(bn.spec, codec.NewDecodingReader(bytes.NewReader(optimisticUpdateValue), uint64(len(optimisticUpdateValue))))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -130,9 +165,9 @@ func (bn *BeaconNetwork) getContent(contentType storage.ContentType, beaconConte
|
||||||
}
|
}
|
||||||
|
|
||||||
contentKey := storage.NewContentKey(contentType, contentKeyBytes).Encode()
|
contentKey := storage.NewContentKey(contentType, contentKeyBytes).Encode()
|
||||||
contentId := bn.PortalProtocol.ToContentId(contentKey)
|
contentId := bn.portalProtocol.ToContentId(contentKey)
|
||||||
|
|
||||||
res, err := bn.PortalProtocol.Get(contentKey, contentId)
|
res, err := bn.portalProtocol.Get(contentKey, contentId)
|
||||||
// other error
|
// other error
|
||||||
if err != nil && !errors.Is(err, storage.ErrContentNotFound) {
|
if err != nil && !errors.Is(err, storage.ErrContentNotFound) {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -142,10 +177,75 @@ func (bn *BeaconNetwork) getContent(contentType storage.ContentType, beaconConte
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
content, _, err := bn.PortalProtocol.ContentLookup(contentKey, contentId)
|
content, _, err := bn.portalProtocol.ContentLookup(contentKey, contentId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return content, nil
|
return content, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (bn *BeaconNetwork) validateContent(contentKey []byte, content []byte) error {
|
||||||
|
switch storage.ContentType(contentKey[0]) {
|
||||||
|
case LightClientUpdate:
|
||||||
|
var lightClientUpdateRange LightClientUpdateRange = make([]ForkedLightClientUpdate, 0)
|
||||||
|
return lightClientUpdateRange.Deserialize(bn.spec, codec.NewDecodingReader(bytes.NewReader(content), uint64(len(content))))
|
||||||
|
case LightClientBootstrap:
|
||||||
|
var forkedLightClientBootstrap ForkedLightClientBootstrap
|
||||||
|
return forkedLightClientBootstrap.Deserialize(bn.spec, codec.NewDecodingReader(bytes.NewReader(content), uint64(len(content))))
|
||||||
|
// TODO: IF WE NEED LIGHT CLIENT VERIFY
|
||||||
|
case LightClientFinalityUpdate:
|
||||||
|
var forkedLightClientFinalityUpdate ForkedLightClientFinalityUpdate
|
||||||
|
return forkedLightClientFinalityUpdate.Deserialize(bn.spec, codec.NewDecodingReader(bytes.NewReader(content), uint64(len(content))))
|
||||||
|
// TODO: IF WE NEED LIGHT CLIENT VERIFY
|
||||||
|
case LightClientOptimisticUpdate:
|
||||||
|
var forkedLightClientOptimisticUpdate ForkedLightClientOptimisticUpdate
|
||||||
|
return forkedLightClientOptimisticUpdate.Deserialize(bn.spec, codec.NewDecodingReader(bytes.NewReader(content), uint64(len(content))))
|
||||||
|
// TODO: VERIFY
|
||||||
|
case HistoricalSummaries:
|
||||||
|
var historicalSummaries HistoricalSummariesProof
|
||||||
|
return historicalSummaries.Deserialize(codec.NewDecodingReader(bytes.NewReader(content), uint64(len(content))))
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unknown content type %v", contentKey[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bn *BeaconNetwork) validateContents(contentKeys [][]byte, contents [][]byte) error {
|
||||||
|
for i, content := range contents {
|
||||||
|
contentKey := contentKeys[i]
|
||||||
|
err := bn.validateContent(contentKey, content)
|
||||||
|
if err != nil {
|
||||||
|
bn.log.Error("content validate failed", "contentKey", hexutil.Encode(contentKey), "content", hexutil.Encode(content), "err", err)
|
||||||
|
return fmt.Errorf("content validate failed with content key %x and content %x", contentKey, content)
|
||||||
|
}
|
||||||
|
contentId := bn.portalProtocol.ToContentId(contentKey)
|
||||||
|
err = bn.portalProtocol.Put(contentKey, contentId, content)
|
||||||
|
if err != nil {
|
||||||
|
bn.log.Error("put content failed", "contentKey", hexutil.Encode(contentKey), "content", hexutil.Encode(content), "err", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bn *BeaconNetwork) processContentLoop(ctx context.Context) {
|
||||||
|
contentChan := bn.portalProtocol.GetContent()
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
case contentElement := <-contentChan:
|
||||||
|
err := bn.validateContents(contentElement.ContentKeys, contentElement.Contents)
|
||||||
|
if err != nil {
|
||||||
|
bn.log.Error("validate content failed", "err", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
gossippedNum, err := bn.portalProtocol.Gossip(&contentElement.Node, contentElement.ContentKeys, contentElement.Contents)
|
||||||
|
bn.log.Trace("gossippedNum", "gossippedNum", gossippedNum)
|
||||||
|
if err != nil {
|
||||||
|
bn.log.Error("gossip failed", "err", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
220
portalnetwork/beacon/beacon_network_test.go
Normal file
220
portalnetwork/beacon/beacon_network_test.go
Normal file
|
|
@ -0,0 +1,220 @@
|
||||||
|
package beacon
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/internal/testlog"
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/discover/portalwire"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||||
|
"github.com/ethereum/go-ethereum/portalnetwork/storage"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func setupBeaconNetwork(addr string, bootNodes []*enode.Node) (*BeaconNetwork, error) {
|
||||||
|
conf := discover.DefaultPortalProtocolConfig()
|
||||||
|
if addr != "" {
|
||||||
|
conf.ListenAddr = addr
|
||||||
|
}
|
||||||
|
if bootNodes != nil {
|
||||||
|
conf.BootstrapNodes = bootNodes
|
||||||
|
}
|
||||||
|
|
||||||
|
addr1, err := net.ResolveUDPAddr("udp", conf.ListenAddr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
conn, err := net.ListenUDP("udp", addr1)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
privKey, err := crypto.GenerateKey()
|
||||||
|
if err != nil {
|
||||||
|
panic("couldn't generate key: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
discCfg := discover.Config{
|
||||||
|
PrivateKey: privKey,
|
||||||
|
NetRestrict: conf.NetRestrict,
|
||||||
|
Bootnodes: conf.BootstrapNodes,
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeDB, err := enode.OpenDB(conf.NodeDBPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
localNode := enode.NewLocalNode(nodeDB, privKey)
|
||||||
|
localNode.SetFallbackIP(net.IP{127, 0, 0, 1})
|
||||||
|
localNode.Set(discover.Tag)
|
||||||
|
|
||||||
|
var addrs []net.Addr
|
||||||
|
if conf.NodeIP != nil {
|
||||||
|
localNode.SetStaticIP(conf.NodeIP)
|
||||||
|
} else {
|
||||||
|
addrs, err = net.InterfaceAddrs()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, address := range addrs {
|
||||||
|
// check ip addr is loopback addr
|
||||||
|
if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
|
||||||
|
if ipnet.IP.To4() != nil {
|
||||||
|
localNode.SetStaticIP(ipnet.IP)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
discV5, err := discover.ListenV5(conn, localNode, discCfg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
contentQueue := make(chan *discover.ContentElement, 50)
|
||||||
|
|
||||||
|
portalProtocol, err := discover.NewPortalProtocol(conf, string(portalwire.BeaconLightClientNetwork), privKey, conn, localNode, discV5, &storage.MockStorage{Db: make(map[string][]byte)}, contentQueue)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewBeaconNetwork(portalProtocol), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBeaconNetworkContent(t *testing.T) {
|
||||||
|
logger := testlog.Logger(t, log.LvlTrace)
|
||||||
|
node1, err := setupBeaconNetwork(":6666", nil)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
node1.log = logger
|
||||||
|
node1.portalProtocol.Log = logger
|
||||||
|
err = node1.Start()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
time.Sleep(10 * time.Second)
|
||||||
|
|
||||||
|
node2, err := setupBeaconNetwork(":6667", []*enode.Node{node1.portalProtocol.Self()})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
node2.log = logger
|
||||||
|
node2.portalProtocol.Log = logger
|
||||||
|
err = node2.Start()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
time.Sleep(10 * time.Second)
|
||||||
|
|
||||||
|
node3, err := setupBeaconNetwork(":6668", []*enode.Node{node1.portalProtocol.Self()})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
node3.log = logger
|
||||||
|
node3.portalProtocol.Log = logger
|
||||||
|
err = node3.Start()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
time.Sleep(10 * time.Second)
|
||||||
|
|
||||||
|
filePath := "testdata/light_client_updates_by_range.json"
|
||||||
|
jsonStr, _ := os.ReadFile(filePath)
|
||||||
|
|
||||||
|
var result map[string]interface{}
|
||||||
|
err = json.Unmarshal(jsonStr, &result)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
id := node1.portalProtocol.Self().ID()
|
||||||
|
for _, v := range result {
|
||||||
|
kBytes, _ := hexutil.Decode(v.(map[string]interface{})["content_key"].(string))
|
||||||
|
vBytes, _ := hexutil.Decode(v.(map[string]interface{})["content_value"].(string))
|
||||||
|
contentKey := storage.NewContentKey(LightClientUpdate, kBytes).Encode()
|
||||||
|
_, err = node1.portalProtocol.Gossip(&id, [][]byte{contentKey}, [][]byte{vBytes})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
time.Sleep(3 * time.Second)
|
||||||
|
|
||||||
|
contentId := node2.portalProtocol.ToContentId(contentKey)
|
||||||
|
get, err := node2.portalProtocol.Get(contentKey, contentId)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, vBytes, get)
|
||||||
|
}
|
||||||
|
|
||||||
|
filePath1 := "testdata/light_client_finality_update.json"
|
||||||
|
jsonStr1, _ := os.ReadFile(filePath1)
|
||||||
|
|
||||||
|
var result1 map[string]interface{}
|
||||||
|
err = json.Unmarshal(jsonStr1, &result1)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
for _, v := range result1 {
|
||||||
|
kBytes1, _ := hexutil.Decode(v.(map[string]interface{})["content_key"].(string))
|
||||||
|
vBytes1, _ := hexutil.Decode(v.(map[string]interface{})["content_value"].(string))
|
||||||
|
|
||||||
|
contentKey1 := storage.NewContentKey(LightClientFinalityUpdate, kBytes1).Encode()
|
||||||
|
|
||||||
|
id = node1.portalProtocol.Self().ID()
|
||||||
|
_, err = node1.portalProtocol.Gossip(&id, [][]byte{contentKey1}, [][]byte{vBytes1})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
time.Sleep(3 * time.Second)
|
||||||
|
|
||||||
|
contentId1 := node2.portalProtocol.ToContentId(contentKey1)
|
||||||
|
get1, err := node2.portalProtocol.Get(contentKey1, contentId1)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, vBytes1, get1)
|
||||||
|
}
|
||||||
|
|
||||||
|
filePath2 := "testdata/light_client_optimistic_update.json"
|
||||||
|
jsonStr2, _ := os.ReadFile(filePath2)
|
||||||
|
|
||||||
|
var result2 map[string]interface{}
|
||||||
|
err = json.Unmarshal(jsonStr2, &result2)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
for _, v := range result2 {
|
||||||
|
kBytes2, _ := hexutil.Decode(v.(map[string]interface{})["content_key"].(string))
|
||||||
|
vBytes2, _ := hexutil.Decode(v.(map[string]interface{})["content_value"].(string))
|
||||||
|
|
||||||
|
contentKey2 := storage.NewContentKey(LightClientOptimisticUpdate, kBytes2).Encode()
|
||||||
|
|
||||||
|
id = node1.portalProtocol.Self().ID()
|
||||||
|
_, err = node1.portalProtocol.Gossip(&id, [][]byte{contentKey2}, [][]byte{vBytes2})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
time.Sleep(3 * time.Second)
|
||||||
|
|
||||||
|
contentId2 := node2.portalProtocol.ToContentId(contentKey2)
|
||||||
|
get2, err := node2.portalProtocol.Get(contentKey2, contentId2)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, vBytes2, get2)
|
||||||
|
}
|
||||||
|
|
||||||
|
filePath3 := "testdata/light_client_bootstrap.json"
|
||||||
|
jsonStr3, _ := os.ReadFile(filePath3)
|
||||||
|
|
||||||
|
var result3 map[string]interface{}
|
||||||
|
err = json.Unmarshal(jsonStr3, &result3)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
for _, v := range result3 {
|
||||||
|
kBytes3, _ := hexutil.Decode(v.(map[string]interface{})["content_key"].(string))
|
||||||
|
vBytes3, _ := hexutil.Decode(v.(map[string]interface{})["content_value"].(string))
|
||||||
|
|
||||||
|
contentKey3 := storage.NewContentKey(LightClientBootstrap, kBytes3).Encode()
|
||||||
|
|
||||||
|
id = node1.portalProtocol.Self().ID()
|
||||||
|
_, err = node1.portalProtocol.Gossip(&id, [][]byte{contentKey3}, [][]byte{vBytes3})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
time.Sleep(3 * time.Second)
|
||||||
|
|
||||||
|
contentId3 := node2.portalProtocol.ToContentId(contentKey3)
|
||||||
|
get3, err := node2.portalProtocol.Get(contentKey3, contentId3)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, vBytes3, get3)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -27,14 +27,14 @@ func (api *PortalLightApi) GetCheckpointData(checkpointHash tree.Root) (*capella
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *PortalLightApi) GetFinalityData() (*capella.LightClientFinalityUpdate, error) {
|
func (api *PortalLightApi) GetFinalityData() (*capella.LightClientFinalityUpdate, error) {
|
||||||
expectedCurrentSlot := api.bn.Spec.TimeToSlot(zrntcommon.Timestamp(time.Now().Unix()), zrntcommon.Timestamp(BeaconGenesisTime))
|
expectedCurrentSlot := api.bn.spec.TimeToSlot(zrntcommon.Timestamp(time.Now().Unix()), zrntcommon.Timestamp(BeaconGenesisTime))
|
||||||
recentEpochStart := expectedCurrentSlot - (expectedCurrentSlot % api.bn.Spec.SLOTS_PER_EPOCH) + 1
|
recentEpochStart := expectedCurrentSlot - (expectedCurrentSlot % api.bn.spec.SLOTS_PER_EPOCH) + 1
|
||||||
|
|
||||||
return api.bn.GetFinalityUpdate(uint64(recentEpochStart))
|
return api.bn.GetFinalityUpdate(uint64(recentEpochStart))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *PortalLightApi) GetOptimisticData() (*capella.LightClientOptimisticUpdate, error) {
|
func (api *PortalLightApi) GetOptimisticData() (*capella.LightClientOptimisticUpdate, error) {
|
||||||
expectedCurrentSlot := api.bn.Spec.TimeToSlot(zrntcommon.Timestamp(time.Now().Unix()), zrntcommon.Timestamp(BeaconGenesisTime))
|
expectedCurrentSlot := api.bn.spec.TimeToSlot(zrntcommon.Timestamp(time.Now().Unix()), zrntcommon.Timestamp(BeaconGenesisTime))
|
||||||
|
|
||||||
return api.bn.GetOptimisticUpdate(uint64(expectedCurrentSlot))
|
return api.bn.GetOptimisticUpdate(uint64(expectedCurrentSlot))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -508,7 +508,7 @@ func (h *HistoryNetwork) processContentLoop(ctx context.Context) {
|
||||||
h.log.Error("validate content failed", "err", err)
|
h.log.Error("validate content failed", "err", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
gossippedNum, err := h.portalProtocol.NeighborhoodGossip(&contentElement.Node, contentElement.ContentKeys, contentElement.Contents)
|
gossippedNum, err := h.portalProtocol.Gossip(&contentElement.Node, contentElement.ContentKeys, contentElement.Contents)
|
||||||
h.log.Trace("gossippedNum", "gossippedNum", gossippedNum)
|
h.log.Trace("gossippedNum", "gossippedNum", gossippedNum)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.log.Error("gossip failed", "err", err)
|
h.log.Error("gossip failed", "err", err)
|
||||||
|
|
|
||||||
|
|
@ -362,22 +362,6 @@ func parseBlockHeaderKeyContent() ([]contentEntry, error) {
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type MockStorage struct {
|
|
||||||
db map[string][]byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MockStorage) Get(contentKey []byte, contentId []byte) ([]byte, error) {
|
|
||||||
if content, ok := m.db[string(contentId)]; ok {
|
|
||||||
return content, nil
|
|
||||||
}
|
|
||||||
return nil, storage.ErrContentNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MockStorage) Put(contentKey []byte, contentId []byte, content []byte) error {
|
|
||||||
m.db[string(contentId)] = content
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func genHistoryNetwork(addr string, bootNodes []*enode.Node) (*HistoryNetwork, error) {
|
func genHistoryNetwork(addr string, bootNodes []*enode.Node) (*HistoryNetwork, error) {
|
||||||
glogger := log.NewGlogHandler(log.NewTerminalHandler(os.Stderr, true))
|
glogger := log.NewGlogHandler(log.NewTerminalHandler(os.Stderr, true))
|
||||||
slogVerbosity := log.FromLegacyLevel(5)
|
slogVerbosity := log.FromLegacyLevel(5)
|
||||||
|
|
@ -448,7 +432,7 @@ func genHistoryNetwork(addr string, bootNodes []*enode.Node) (*HistoryNetwork, e
|
||||||
|
|
||||||
contentQueue := make(chan *discover.ContentElement, 50)
|
contentQueue := make(chan *discover.ContentElement, 50)
|
||||||
|
|
||||||
portalProtocol, err := discover.NewPortalProtocol(conf, string(portalwire.HistoryNetwork), privKey, conn, localNode, discV5, &MockStorage{db: make(map[string][]byte)}, contentQueue)
|
portalProtocol, err := discover.NewPortalProtocol(conf, string(portalwire.HistoryNetwork), privKey, conn, localNode, discV5, &storage.MockStorage{Db: make(map[string][]byte)}, contentQueue)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,10 @@ type ContentKey struct {
|
||||||
data []byte
|
data []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewContentKey(selector ContentType, hash []byte) *ContentKey {
|
func NewContentKey(selector ContentType, data []byte) *ContentKey {
|
||||||
return &ContentKey{
|
return &ContentKey{
|
||||||
selector: selector,
|
selector: selector,
|
||||||
data: hash,
|
data: data,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -30,3 +30,19 @@ type ContentStorage interface {
|
||||||
|
|
||||||
Put(contentKey []byte, contentId []byte, content []byte) error
|
Put(contentKey []byte, contentId []byte, content []byte) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MockStorage struct {
|
||||||
|
Db map[string][]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockStorage) Get(contentKey []byte, contentId []byte) ([]byte, error) {
|
||||||
|
if content, ok := m.Db[string(contentId)]; ok {
|
||||||
|
return content, nil
|
||||||
|
}
|
||||||
|
return nil, ErrContentNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockStorage) Put(contentKey []byte, contentId []byte, content []byte) error {
|
||||||
|
m.Db[string(contentId)] = content
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue