From f2b951a59434ccef51b11ca74e0a31c4ccc47c95 Mon Sep 17 00:00:00 2001 From: Chen Kai <281165273grape@gmail.com> Date: Wed, 20 Mar 2024 19:48:00 +0800 Subject: [PATCH 1/2] feat:beacon rpc Signed-off-by: Chen Kai <281165273grape@gmail.com> --- cmd/shisui/config_test.go | 2 +- cmd/shisui/main.go | 106 ++++++++++++++++-- p2p/discover/api.go | 77 ++++--------- p2p/discover/portal_protocol.go | 82 +++----------- p2p/discover/portal_protocol_test.go | 54 ++++++++- portalnetwork/beacon/api.go | 75 +++++++++++++ portalnetwork/beacon/beacon_network.go | 1 + portalnetwork/history/api.go | 75 +++++++++++++ portalnetwork/history/history_network_test.go | 57 +++++++++- 9 files changed, 400 insertions(+), 129 deletions(-) create mode 100644 portalnetwork/beacon/api.go create mode 100644 portalnetwork/beacon/beacon_network.go create mode 100644 portalnetwork/history/api.go diff --git a/cmd/shisui/config_test.go b/cmd/shisui/config_test.go index cffe1eca201b..d75bd6628b2e 100644 --- a/cmd/shisui/config_test.go +++ b/cmd/shisui/config_test.go @@ -24,7 +24,7 @@ func TestGenConfig(t *testing.T) { ctx := cli.NewContext(nil, flagSet, nil) ctx.Command = command - config, err := getPortalHistoryConfig(ctx) + config, err := getPortalConfig(ctx) require.NoError(t, err) require.Equal(t, config.DataCapacity, size) diff --git a/cmd/shisui/main.go b/cmd/shisui/main.go index daa98624ea06..312f291eb586 100644 --- a/cmd/shisui/main.go +++ b/cmd/shisui/main.go @@ -4,6 +4,7 @@ import ( "crypto/ecdsa" "fmt" "net" + "net/http" "strings" "os" @@ -16,8 +17,10 @@ import ( "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/beacon" "github.com/ethereum/go-ethereum/portalnetwork/history" "github.com/ethereum/go-ethereum/portalnetwork/storage/sqlite" + "github.com/ethereum/go-ethereum/rpc" "github.com/urfave/cli/v2" ) @@ -60,7 +63,7 @@ func main() { } func shisui(ctx *cli.Context) error { - config, err := getPortalHistoryConfig(ctx) + config, err := getPortalConfig(ctx) if err != nil { return nil } @@ -68,7 +71,8 @@ func shisui(ctx *cli.Context) error { glogger := log.NewGlogHandler(log.NewTerminalHandler(os.Stderr, true)) slogVerbosity := log.FromLegacyLevel(config.LogLevel) glogger.Verbosity(slogVerbosity) - log.SetDefault(log.NewLogger(glogger)) + defaultLogger := log.NewLogger(glogger) + log.SetDefault(defaultLogger) nodeId := enode.PubkeyToIDV4(&config.PrivateKey.PublicKey) contentStorage, err := sqlite.NewContentStorage(config.DataCapacity, nodeId, config.DataDir) @@ -76,9 +80,60 @@ func shisui(ctx *cli.Context) error { return err } + addr, err := net.ResolveUDPAddr("udp", config.Protocol.ListenAddr) + if err != nil { + return err + } + conn, err := net.ListenUDP("udp", addr) + if err != nil { + return err + } + + discCfg := discover.Config{ + PrivateKey: config.PrivateKey, + NetRestrict: config.Protocol.NetRestrict, + Bootnodes: config.Protocol.BootstrapNodes, + Log: defaultLogger, + } + + nodeDB, err := enode.OpenDB(config.Protocol.NodeDBPath) + if err != nil { + return err + } + + localNode := enode.NewLocalNode(nodeDB, config.PrivateKey) + localNode.SetFallbackIP(net.IP{127, 0, 0, 1}) + localNode.Set(discover.Tag) + + var addrs []net.Addr + if config.Protocol.NodeIP != nil { + localNode.SetStaticIP(config.Protocol.NodeIP) + } else { + addrs, err = net.InterfaceAddrs() + + if err != nil { + return 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 err + } + contentQueue := make(chan *discover.ContentElement, 50) - protocol, err := discover.NewPortalProtocol(config.Protocol, string(portalwire.HistoryNetwork), config.PrivateKey, contentStorage, contentQueue) + historyProtocol, err := discover.NewPortalProtocol(config.Protocol, string(portalwire.HistoryNetwork), config.PrivateKey, conn, localNode, discV5, contentStorage, contentQueue) if err != nil { return err @@ -89,19 +144,18 @@ func shisui(ctx *cli.Context) error { return err } - historyNetwork := history.NewHistoryNetwork(protocol, &accumulator) + historyNetwork := history.NewHistoryNetwork(historyProtocol, &accumulator) err = historyNetwork.Start() if err != nil { return err } defer historyNetwork.Stop() - discover.StartHistoryRpcServer(protocol, config.RpcAddr) - + startPortalRpcServer(discover.NewDiscV5API(discV5), discover.NewPortalAPI(historyProtocol), nil, config.RpcAddr) return nil } -func getPortalHistoryConfig(ctx *cli.Context) (*Config, error) { +func getPortalConfig(ctx *cli.Context) (*Config, error) { config := &Config{ Protocol: discover.DefaultPortalProtocolConfig(), } @@ -167,3 +221,41 @@ func setPrivateKey(ctx *cli.Context, config *Config) error { config.PrivateKey = privateKey return nil } + +func startPortalRpcServer(discV5API *discover.DiscV5API, historyAPI *discover.PortalProtocolAPI, beaconAPI *discover.PortalProtocolAPI, addr string) error { + disv5 := discV5API + + server := rpc.NewServer() + err := server.RegisterName("discv5", disv5) + if err != nil { + return err + } + + var historyNetworkAPI *history.API + if historyAPI != nil { + historyNetworkAPI = history.NewHistoryNetworkAPI(historyAPI) + err = server.RegisterName("portal", historyNetworkAPI) + + if err != nil { + return err + } + } + + var beaconNetworkAPI *beacon.API + if beaconAPI != nil { + beaconNetworkAPI = beacon.NewBeaconNetworkAPI(beaconAPI) + err = server.RegisterName("portal", beaconNetworkAPI) + + if err != nil { + return err + } + } + + httpServer := &http.Server{ + Addr: addr, + Handler: server, + } + + httpServer.ListenAndServe() + return nil +} diff --git a/p2p/discover/api.go b/p2p/discover/api.go index e14ddddac086..6d6f07afbff8 100644 --- a/p2p/discover/api.go +++ b/p2p/discover/api.go @@ -2,12 +2,10 @@ package discover import ( "errors" - "net/http" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/p2p/discover/portalwire" "github.com/ethereum/go-ethereum/p2p/enode" - "github.com/ethereum/go-ethereum/rpc" "github.com/holiman/uint256" ) @@ -17,7 +15,7 @@ type DiscV5API struct { DiscV5 *UDPv5 } -func NewAPI(discV5 *UDPv5) *DiscV5API { +func NewDiscV5API(discV5 *UDPv5) *DiscV5API { return &DiscV5API{discV5} } @@ -73,30 +71,6 @@ type Enrs struct { Enrs []string `json:"enrs"` } -func StartHistoryRpcServer(protocol *PortalProtocol, addr string) error { - disv5 := NewAPI(protocol.DiscV5) - portal := NewPortalAPI(protocol) - - server := rpc.NewServer() - err := server.RegisterName("discv5", disv5) - if err != nil { - return err - } - err = server.RegisterName("portal", portal) - - if err != nil { - return err - } - - httpServer := &http.Server{ - Addr: addr, - Handler: server, - } - - httpServer.ListenAndServe() - return nil -} - func (d *DiscV5API) NodeInfo() *NodeInfo { n := d.DiscV5.LocalNode().Node() @@ -236,19 +210,17 @@ func (d *DiscV5API) RecursiveFindNodes(nodeId string) ([]string, error) { return enrs, nil } -type PortalAPI struct { - *DiscV5API +type PortalProtocolAPI struct { portalProtocol *PortalProtocol } -func NewPortalAPI(portalProtocol *PortalProtocol) *PortalAPI { - return &PortalAPI{ - DiscV5API: &DiscV5API{portalProtocol.DiscV5}, +func NewPortalAPI(portalProtocol *PortalProtocol) *PortalProtocolAPI { + return &PortalProtocolAPI{ portalProtocol: portalProtocol, } } -func (p *PortalAPI) NodeInfo() *NodeInfo { +func (p *PortalProtocolAPI) NodeInfo() *NodeInfo { n := p.portalProtocol.localNode.Node() return &NodeInfo{ @@ -258,7 +230,7 @@ func (p *PortalAPI) NodeInfo() *NodeInfo { } } -func (p *PortalAPI) HistoryRoutingTableInfo() *RoutingTableInfo { +func (p *PortalProtocolAPI) RoutingTableInfo() *RoutingTableInfo { n := p.portalProtocol.localNode.Node() return &RoutingTableInfo{ @@ -267,7 +239,7 @@ func (p *PortalAPI) HistoryRoutingTableInfo() *RoutingTableInfo { } } -func (p *PortalAPI) HistoryAddEnr(enr string) (bool, error) { +func (p *PortalProtocolAPI) AddEnr(enr string) (bool, error) { n, err := enode.Parse(enode.ValidSchemes, enr) if err != nil { return false, err @@ -279,7 +251,7 @@ func (p *PortalAPI) HistoryAddEnr(enr string) (bool, error) { return true, nil } -func (p *PortalAPI) AddEnrs(enrs []string) bool { +func (p *PortalProtocolAPI) AddEnrs(enrs []string) bool { // Note: unspecified RPC, but useful for our local testnet test for _, enr := range enrs { n, err := enode.Parse(enode.ValidSchemes, enr) @@ -295,7 +267,7 @@ func (p *PortalAPI) AddEnrs(enrs []string) bool { return true } -func (p *PortalAPI) HistoryGetEnr(nodeId string) (string, error) { +func (p *PortalProtocolAPI) GetEnr(nodeId string) (string, error) { id, err := enode.ParseID(nodeId) if err != nil { return "", err @@ -313,7 +285,7 @@ func (p *PortalAPI) HistoryGetEnr(nodeId string) (string, error) { return n.String(), nil } -func (p *PortalAPI) HistoryDeleteEnr(nodeId string) (bool, error) { +func (p *PortalProtocolAPI) DeleteEnr(nodeId string) (bool, error) { id, err := enode.ParseID(nodeId) if err != nil { return false, err @@ -328,7 +300,7 @@ func (p *PortalAPI) HistoryDeleteEnr(nodeId string) (bool, error) { return true, nil } -func (p *PortalAPI) HistoryLookupEnr(nodeId string) (string, error) { +func (p *PortalProtocolAPI) LookupEnr(nodeId string) (string, error) { id, err := enode.ParseID(nodeId) if err != nil { return "", err @@ -343,7 +315,7 @@ func (p *PortalAPI) HistoryLookupEnr(nodeId string) (string, error) { return enr.String(), nil } -func (p *PortalAPI) HistoryPing(enr string) (*PortalPongResp, error) { +func (p *PortalProtocolAPI) Ping(enr string) (*PortalPongResp, error) { n, err := enode.Parse(enode.ValidSchemes, enr) if err != nil { return nil, err @@ -372,7 +344,7 @@ func (p *PortalAPI) HistoryPing(enr string) (*PortalPongResp, error) { }, nil } -func (p *PortalAPI) HistoryFindNodes(enr string, distances []uint) ([]string, error) { +func (p *PortalProtocolAPI) FindNodes(enr string, distances []uint) ([]string, error) { n, err := enode.Parse(enode.ValidSchemes, enr) if err != nil { return nil, err @@ -390,7 +362,7 @@ func (p *PortalAPI) HistoryFindNodes(enr string, distances []uint) ([]string, er return enrs, nil } -func (p *PortalAPI) HistoryFindContent(enr string, contentKey string) (interface{}, error) { +func (p *PortalProtocolAPI) FindContent(enr string, contentKey string) (interface{}, error) { n, err := enode.Parse(enode.ValidSchemes, enr) if err != nil { return nil, err @@ -412,14 +384,14 @@ func (p *PortalAPI) HistoryFindContent(enr string, contentKey string) (interface Content: hexutil.Encode(findContent.([]byte)), UtpTransfer: false, } - p.portalProtocol.log.Trace("HistoryFindContent", "contentInfo", contentInfo) + p.portalProtocol.log.Trace("FindContent", "contentInfo", contentInfo) return contentInfo, nil case portalwire.ContentConnIdSelector: contentInfo := &ContentInfo{ Content: hexutil.Encode(findContent.([]byte)), UtpTransfer: true, } - p.portalProtocol.log.Trace("HistoryFindContent", "contentInfo", contentInfo) + p.portalProtocol.log.Trace("FindContent", "contentInfo", contentInfo) return contentInfo, nil default: enrs := make([]string, 0) @@ -427,14 +399,14 @@ func (p *PortalAPI) HistoryFindContent(enr string, contentKey string) (interface enrs = append(enrs, r.String()) } - p.portalProtocol.log.Trace("HistoryFindContent", "enrs", enrs) + p.portalProtocol.log.Trace("FindContent", "enrs", enrs) return &Enrs{ Enrs: enrs, }, nil } } -func (p *PortalAPI) HistoryOffer(enr string, contentKey string, contentValue string) (string, error) { +func (p *PortalProtocolAPI) Offer(enr string, contentKey string, contentValue string) (string, error) { n, err := enode.Parse(enode.ValidSchemes, enr) if err != nil { return "", err @@ -470,7 +442,7 @@ func (p *PortalAPI) HistoryOffer(enr string, contentKey string, contentValue str return hexutil.Encode(accept), nil } -func (p *PortalAPI) HistoryRecursiveFindNodes(nodeId string) ([]string, error) { +func (p *PortalProtocolAPI) RecursiveFindNodes(nodeId string) ([]string, error) { findNodes := p.portalProtocol.Lookup(enode.HexID(nodeId)) enrs := make([]string, 0, len(findNodes)) @@ -481,7 +453,7 @@ func (p *PortalAPI) HistoryRecursiveFindNodes(nodeId string) ([]string, error) { return enrs, nil } -func (p *PortalAPI) HistoryRecursiveFindContent(contentKeyHex string) (*ContentInfo, error) { +func (p *PortalProtocolAPI) RecursiveFindContent(contentKeyHex string) (*ContentInfo, error) { contentKey, err := hexutil.Decode(contentKeyHex) if err != nil { return nil, err @@ -498,7 +470,7 @@ func (p *PortalAPI) HistoryRecursiveFindContent(contentKeyHex string) (*ContentI }, err } -func (p *PortalAPI) HistoryLocalContent(contentKeyHex string) (string, error) { +func (p *PortalProtocolAPI) LocalContent(contentKeyHex string) (string, error) { contentKey, err := hexutil.Decode(contentKeyHex) if err != nil { return "", err @@ -512,7 +484,7 @@ func (p *PortalAPI) HistoryLocalContent(contentKeyHex string) (string, error) { return hexutil.Encode(content), nil } -func (p *PortalAPI) HistoryStore(contentKeyHex string, contextHex string) (bool, error) { +func (p *PortalProtocolAPI) Store(contentKeyHex string, contextHex string) (bool, error) { contentKey, err := hexutil.Decode(contentKeyHex) if err != nil { return false, err @@ -532,8 +504,7 @@ func (p *PortalAPI) HistoryStore(contentKeyHex string, contextHex string) (bool, return true, nil } -// TODO -func (p *PortalAPI) HistoryGossip(contentKeyHex, contentHex string) (int, error) { +func (p *PortalProtocolAPI) Gossip(contentKeyHex, contentHex string) (int, error) { contentKey, err := hexutil.Decode(contentKeyHex) if err != nil { return 0, err @@ -547,6 +518,6 @@ func (p *PortalAPI) HistoryGossip(contentKeyHex, contentHex string) (int, error) } // TODO -func (p *PortalAPI) HistoryTraceRecursiveFindContent(contentKeyHex string) { +func (p *PortalProtocolAPI) TraceRecursiveFindContent(contentKeyHex string) { } diff --git a/p2p/discover/portal_protocol.go b/p2p/discover/portal_protocol.go index 5fb34db6ac1c..adea5eed5f0b 100644 --- a/p2p/discover/portal_protocol.go +++ b/p2p/discover/portal_protocol.go @@ -36,10 +36,6 @@ import ( ) const ( - // This is the fairness knob for the discovery mixer. When looking for peers, we'll - // wait this long for a single source of candidates before moving on and trying other - // sources. - discmixTimeout = 5 * time.Second // TalkResp message is a response message so the session is established and a // regular discv5 packet is assumed for size calculation. @@ -81,15 +77,15 @@ const ( PersistOfferRequestKind byte = 0x02 ) -var ErrNilContentKey = errors.New("content key cannot be nil") +type ClientTag string -var ContentNotFound = storage.ErrContentNotFound +func (c ClientTag) ENRKey() string { return "c" } -type clientTag string +const Tag ClientTag = "shisui" -func (c clientTag) ENRKey() string { return "c" } +var ErrNilContentKey = errors.New("content key cannot be nil") -const tag clientTag = "shisui" +var ContentNotFound = storage.ErrContentNotFound type ContentElement struct { Node enode.ID @@ -169,10 +165,10 @@ type PortalProtocol struct { ListenAddr string localNode *enode.LocalNode log log.Logger - discmix *enode.FairMix PrivateKey *ecdsa.PrivateKey NetRestrict *netutil.Netlist BootstrapNodes []*enode.Node + conn UDPConn validSchemes enr.IdentityScheme radiusCache *fastcache.Cache @@ -190,36 +186,7 @@ func defaultContentIdFunc(contentKey []byte) []byte { return digest[:] } -func NewPortalProtocol(config *PortalProtocolConfig, protocolId string, privateKey *ecdsa.PrivateKey, storage storage.ContentStorage, contentQueue chan *ContentElement, opts ...PortalProtocolOption) (*PortalProtocol, error) { - nodeDB, err := enode.OpenDB(config.NodeDBPath) - if err != nil { - return nil, err - } - - localNode := enode.NewLocalNode(nodeDB, privateKey) - localNode.SetFallbackIP(net.IP{127, 0, 0, 1}) - localNode.Set(tag) - - if config.NodeIP != nil { - localNode.SetStaticIP(config.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 - } - } - } - } - +func NewPortalProtocol(config *PortalProtocolConfig, protocolId string, privateKey *ecdsa.PrivateKey, conn UDPConn, localNode *enode.LocalNode, discV5 *UDPv5, storage storage.ContentStorage, contentQueue chan *ContentElement, opts ...PortalProtocolOption) (*PortalProtocol, error) { closeCtx, cancelCloseCtx := context.WithCancel(context.Background()) protocol := &PortalProtocol{ @@ -239,6 +206,8 @@ func NewPortalProtocol(config *PortalProtocolConfig, protocolId string, privateK toContentId: defaultContentIdFunc, contentQueue: contentQueue, offerQueue: make(chan *OfferRequestWithNode, concurrentOffers), + conn: conn, + DiscV5: discV5, } for _, opt := range opts { @@ -292,18 +261,8 @@ func (p *PortalProtocol) RoutingTableInfo() [][]string { return nodes } -func (p *PortalProtocol) setupUDPListening() (*net.UDPConn, error) { - listenAddr := p.ListenAddr - - addr, err := net.ResolveUDPAddr("udp", listenAddr) - if err != nil { - return nil, err - } - conn, err := net.ListenUDP("udp", addr) - if err != nil { - return nil, err - } - laddr := conn.LocalAddr().(*net.UDPAddr) +func (p *PortalProtocol) setupUDPListening() error { + laddr := p.conn.LocalAddr().(*net.UDPAddr) p.localNode.SetFallbackUDP(laddr.Port) p.log.Debug("UDP listener up", "addr", laddr) // TODO: NAT @@ -315,6 +274,7 @@ func (p *PortalProtocol) setupUDPListening() (*net.UDPConn, error) { // } //} + var err error p.packetRouter = utp.NewPacketRouter( func(buf []byte, addr *net.UDPAddr) (int, error) { nodes := p.table.Nodes() @@ -351,24 +311,22 @@ func (p *PortalProtocol) setupUDPListening() (*net.UDPConn, error) { } if err != nil { - return nil, err + return err } - p.utpSm, err = utp.NewSocketManagerWithOptions("utp", laddr, utp.WithLogger(logger.Named(listenAddr)), utp.WithPacketRouter(p.packetRouter), utp.WithMaxPacketSize(1145)) + p.utpSm, err = utp.NewSocketManagerWithOptions("utp", laddr, utp.WithLogger(logger.Named(p.ListenAddr)), utp.WithPacketRouter(p.packetRouter), utp.WithMaxPacketSize(1145)) if err != nil { - return nil, err + return err } p.utp, err = utp.ListenUTPOptions("utp", (*utp.Addr)(laddr), utp.WithSocketManager(p.utpSm)) if err != nil { - return nil, err + return err } - return conn, nil + return nil } func (p *PortalProtocol) setupDiscV5AndTable() error { - p.discmix = enode.NewFairMix(discmixTimeout) - - conn, err := p.setupUDPListening() + err := p.setupUDPListening() if err != nil { return err } @@ -379,10 +337,6 @@ func (p *PortalProtocol) setupDiscV5AndTable() error { Bootnodes: p.BootstrapNodes, Log: p.log, } - p.DiscV5, err = ListenV5(conn, p.localNode, cfg) - if err != nil { - return err - } p.table, err = newMeteredTable(p, p.localNode.Database(), cfg) if err != nil { diff --git a/p2p/discover/portal_protocol_test.go b/p2p/discover/portal_protocol_test.go index 8cdcf881ad12..b6c061bb0525 100644 --- a/p2p/discover/portal_protocol_test.go +++ b/p2p/discover/portal_protocol_test.go @@ -48,8 +48,60 @@ func setupLocalPortalNode(addr string, bootNodes []*enode.Node) (*PortalProtocol 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 := newkey() + + discCfg := 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(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 := ListenV5(conn, localNode, discCfg) + if err != nil { + return nil, err + } + contentQueue := make(chan *ContentElement, 50) - portalProtocol, err := NewPortalProtocol(conf, string(portalwire.HistoryNetwork), newkey(), &MockStorage{db: make(map[string][]byte)}, contentQueue) + portalProtocol, err := NewPortalProtocol(conf, string(portalwire.HistoryNetwork), privKey, conn, localNode, discV5, &MockStorage{db: make(map[string][]byte)}, contentQueue) if err != nil { return nil, err } diff --git a/portalnetwork/beacon/api.go b/portalnetwork/beacon/api.go new file mode 100644 index 000000000000..9afaa1b45aa7 --- /dev/null +++ b/portalnetwork/beacon/api.go @@ -0,0 +1,75 @@ +package beacon + +import ( + "github.com/ethereum/go-ethereum/p2p/discover" +) + +type API struct { + *discover.PortalProtocolAPI +} + +func (p *API) BeaconRoutingTableInfo() *discover.RoutingTableInfo { + return p.RoutingTableInfo() +} + +func (p *API) BeaconAddEnr(enr string) (bool, error) { + return p.AddEnr(enr) +} + +func (p *API) BeaconGetEnr(nodeId string) (string, error) { + return p.GetEnr(nodeId) +} + +func (p *API) BeaconDeleteEnr(nodeId string) (bool, error) { + return p.DeleteEnr(nodeId) +} + +func (p *API) BeaconLookupEnr(nodeId string) (string, error) { + return p.LookupEnr(nodeId) +} + +func (p *API) BeaconPing(enr string) (*discover.PortalPongResp, error) { + return p.Ping(enr) +} + +func (p *API) BeaconFindNodes(enr string, distances []uint) ([]string, error) { + return p.FindNodes(enr, distances) +} + +func (p *API) BeaconFindContent(enr string, contentKey string) (interface{}, error) { + return p.FindContent(enr, contentKey) +} + +func (p *API) BeaconOffer(enr string, contentKey string, contentValue string) (string, error) { + return p.Offer(enr, contentKey, contentValue) +} + +func (p *API) BeaconRecursiveFindNodes(nodeId string) ([]string, error) { + return p.RecursiveFindNodes(nodeId) +} + +func (p *API) BeaconRecursiveFindContent(contentKeyHex string) (*discover.ContentInfo, error) { + return p.RecursiveFindContent(contentKeyHex) +} + +func (p *API) BeaconLocalContent(contentKeyHex string) (string, error) { + return p.LocalContent(contentKeyHex) +} + +func (p *API) BeaconStore(contentKeyHex string, contextHex string) (bool, error) { + return p.Store(contentKeyHex, contextHex) +} + +func (p *API) BeaconGossip(contentKeyHex, contentHex string) (int, error) { + return p.Gossip(contentKeyHex, contentHex) +} + +func (p *API) BeaconTraceRecursiveFindContent(contentKeyHex string) { + p.TraceRecursiveFindContent(contentKeyHex) +} + +func NewBeaconNetworkAPI(BeaconAPI *discover.PortalProtocolAPI) *API { + return &API{ + BeaconAPI, + } +} diff --git a/portalnetwork/beacon/beacon_network.go b/portalnetwork/beacon/beacon_network.go new file mode 100644 index 000000000000..519aebf0527a --- /dev/null +++ b/portalnetwork/beacon/beacon_network.go @@ -0,0 +1 @@ +package beacon diff --git a/portalnetwork/history/api.go b/portalnetwork/history/api.go new file mode 100644 index 000000000000..6a51cba7a4f4 --- /dev/null +++ b/portalnetwork/history/api.go @@ -0,0 +1,75 @@ +package history + +import ( + "github.com/ethereum/go-ethereum/p2p/discover" +) + +type API struct { + *discover.PortalProtocolAPI +} + +func (p *API) HistoryRoutingTableInfo() *discover.RoutingTableInfo { + return p.RoutingTableInfo() +} + +func (p *API) HistoryAddEnr(enr string) (bool, error) { + return p.AddEnr(enr) +} + +func (p *API) HistoryGetEnr(nodeId string) (string, error) { + return p.GetEnr(nodeId) +} + +func (p *API) HistoryDeleteEnr(nodeId string) (bool, error) { + return p.DeleteEnr(nodeId) +} + +func (p *API) HistoryLookupEnr(nodeId string) (string, error) { + return p.LookupEnr(nodeId) +} + +func (p *API) HistoryPing(enr string) (*discover.PortalPongResp, error) { + return p.Ping(enr) +} + +func (p *API) HistoryFindNodes(enr string, distances []uint) ([]string, error) { + return p.FindNodes(enr, distances) +} + +func (p *API) HistoryFindContent(enr string, contentKey string) (interface{}, error) { + return p.FindContent(enr, contentKey) +} + +func (p *API) HistoryOffer(enr string, contentKey string, contentValue string) (string, error) { + return p.Offer(enr, contentKey, contentValue) +} + +func (p *API) HistoryRecursiveFindNodes(nodeId string) ([]string, error) { + return p.RecursiveFindNodes(nodeId) +} + +func (p *API) HistoryRecursiveFindContent(contentKeyHex string) (*discover.ContentInfo, error) { + return p.RecursiveFindContent(contentKeyHex) +} + +func (p *API) HistoryLocalContent(contentKeyHex string) (string, error) { + return p.LocalContent(contentKeyHex) +} + +func (p *API) HistoryStore(contentKeyHex string, contextHex string) (bool, error) { + return p.Store(contentKeyHex, contextHex) +} + +func (p *API) HistoryGossip(contentKeyHex, contentHex string) (int, error) { + return p.Gossip(contentKeyHex, contentHex) +} + +func (p *API) HistoryTraceRecursiveFindContent(contentKeyHex string) { + p.TraceRecursiveFindContent(contentKeyHex) +} + +func NewHistoryNetworkAPI(historyAPI *discover.PortalProtocolAPI) *API { + return &API{ + historyAPI, + } +} diff --git a/portalnetwork/history/history_network_test.go b/portalnetwork/history/history_network_test.go index b4fd335727d7..954391498253 100644 --- a/portalnetwork/history/history_network_test.go +++ b/portalnetwork/history/history_network_test.go @@ -8,6 +8,7 @@ import ( "encoding/json" "fmt" "math/big" + "net" "os" "testing" "time" @@ -377,14 +378,64 @@ func genHistoryNetwork(addr string, bootNodes []*enode.Node) (*HistoryNetwork, e conf.BootstrapNodes = bootNodes } - contentQueue := make(chan *discover.ContentElement, 50) + 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 + } - key, err := crypto.GenerateKey() + privKey, err := crypto.GenerateKey() if err != nil { panic("couldn't generate key: " + err.Error()) } - portalProtocol, err := discover.NewPortalProtocol(conf, string(portalwire.HistoryNetwork), key, &MockStorage{db: make(map[string][]byte)}, contentQueue) + 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.HistoryNetwork), privKey, conn, localNode, discV5, &MockStorage{db: make(map[string][]byte)}, contentQueue) if err != nil { return nil, err } From 550ff83a62bc427a1e9596b3cd10d5538cb6a3e3 Mon Sep 17 00:00:00 2001 From: fearlessfe <505380967@qq.com> Date: Thu, 21 Mar 2024 22:40:23 +0800 Subject: [PATCH 2/2] fix: add flags and change default http addr --- cmd/shisui/main.go | 3 +++ cmd/utils/flags.go | 9 +++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/cmd/shisui/main.go b/cmd/shisui/main.go index 312f291eb586..720bebcf207a 100644 --- a/cmd/shisui/main.go +++ b/cmd/shisui/main.go @@ -39,6 +39,9 @@ var ( portalProtocolFlags = []cli.Flag{ utils.PortalUDPListenAddrFlag, utils.PortalUDPPortFlag, + utils.PortalBootNodesFlag, + utils.PortalPrivateKeyFlag, + utils.PortalNetworksFlag, } historyRpcFlags = []cli.Flag{ utils.PortalRPCListenAddrFlag, diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index e859fd0fc2d4..73764f5de4af 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -948,7 +948,6 @@ Please note that --` + MetricsHTTPFlag.Name + ` must be set to start the server. PortalRPCListenAddrFlag = &cli.StringFlag{ Name: "rpc.addr", Usage: "HTTP-RPC server listening interface", - Value: node.DefaultHTTPHost, Category: flags.PortalNetworkCategory, } @@ -1001,10 +1000,16 @@ Please note that --` + MetricsHTTPFlag.Name + ` must be set to start the server. } PortalBootNodesFlag = &cli.StringSliceFlag{ - Name: "bootnode", + Name: "bootnodes", Usage: "bootnode of p2p network with ENR format for portal hive test", Category: flags.PortalNetworkCategory, } + + PortalNetworksFlag = &cli.StringSliceFlag{ + Name: "networks", + Usage: "portal sub networks: history, beacon, state", + Category: flags.PortalNetworkCategory, + } ) var (