feat:beacon rpc

Signed-off-by: Chen Kai <281165273grape@gmail.com>
This commit is contained in:
Chen Kai 2024-03-20 19:48:00 +08:00
parent afc45510ae
commit 317997f25f
9 changed files with 401 additions and 130 deletions

View file

@ -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)

View file

@ -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
}

View file

@ -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) {
}

View file

@ -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,16 +77,16 @@ const (
PersistOfferRequestKind byte = 0x02
)
type ClientTag string
func (c ClientTag) ENRKey() string { return "c" }
const Tag ClientTag = "shisui"
var ErrNilContentKey = errors.New("content key cannot be nil")
var ContentNotFound = storage.ErrContentNotFound
type clientTag string
func (c clientTag) ENRKey() string { return "c" }
const tag clientTag = "shisui"
type ContentElement struct {
Node enode.ID
ContentKeys [][]byte
@ -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 {

View file

@ -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
}

View file

@ -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,
}
}

View file

@ -0,0 +1 @@
package beacon

View file

@ -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,
}
}

View file

@ -8,6 +8,7 @@ import (
"encoding/json"
"fmt"
"math/big"
"net"
"os"
"testing"
"time"
@ -390,14 +391,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
}