diff --git a/p2p/discover/api.go b/p2p/discover/api.go index 4915fa688e2a..6e5c5f28633d 100644 --- a/p2p/discover/api.go +++ b/p2p/discover/api.go @@ -19,6 +19,11 @@ func NewDiscV5API(discV5 *UDPv5) *DiscV5API { return &DiscV5API{discV5} } +type PutContentResult struct { + PeerCount int `json:"peerCount"` + StoredLocally bool `json:"storedLocally"` +} + type NodeInfo struct { NodeId string `json:"nodeId"` Enr string `json:"enr"` @@ -540,6 +545,30 @@ func (p *PortalProtocolAPI) Gossip(contentKeyHex, contentHex string) (int, error return p.portalProtocol.Gossip(&id, [][]byte{contentKey}, [][]byte{content}) } +func (p *PortalProtocolAPI) PutContent(contentKeyHex, contentHex string) (*PutContentResult, error) { + contentKey, err := hexutil.Decode(contentKeyHex) + if err != nil { + return nil, err + } + content, err := hexutil.Decode(contentHex) + if err != nil { + return nil, err + } + shouldStore, err := p.portalProtocol.ShouldStore(contentKey, content) + if err != nil { + return nil, err + } + id := p.portalProtocol.Self().ID() + num, err := p.portalProtocol.Gossip(&id, [][]byte{contentKey}, [][]byte{content}) + if err != nil { + return nil, err + } + return &PutContentResult{ + PeerCount: num, + StoredLocally: shouldStore, + }, nil +} + func (p *PortalProtocolAPI) TraceRecursiveFindContent(contentKeyHex string) (*TraceContentResult, error) { contentKey, err := hexutil.Decode(contentKeyHex) if err != nil { diff --git a/p2p/discover/portal_protocol.go b/p2p/discover/portal_protocol.go index b1be63233c4e..266134a05134 100644 --- a/p2p/discover/portal_protocol.go +++ b/p2p/discover/portal_protocol.go @@ -1861,6 +1861,19 @@ func (p *PortalProtocol) Gossip(srcNodeId *enode.ID, contentKeys [][]byte, conte return len(finalGossipNodes), nil } +// if the content is not in range, return false; else store the content and return true +func (p *PortalProtocol) ShouldStore(contentKey []byte, content []byte) (bool, error) { + if !p.InRange(p.toContentId(contentKey)) { + return false, nil + } + + err := p.storage.Put(contentKey, p.toContentId(contentKey), content) + if err != nil { + return false, err + } + return true, nil +} + func (p *PortalProtocol) Distance(a, b enode.ID) enode.ID { res := [32]byte{} for i := range a { diff --git a/portalnetwork/beacon/api.go b/portalnetwork/beacon/api.go index d62ed49bf4f6..dcc4dfd09427 100644 --- a/portalnetwork/beacon/api.go +++ b/portalnetwork/beacon/api.go @@ -60,10 +60,15 @@ func (p *API) BeaconStore(contentKeyHex string, contextHex string) (bool, error) return p.Store(contentKeyHex, contextHex) } +// deprecated, use BeaconPutContent instead func (p *API) BeaconGossip(contentKeyHex, contentHex string) (int, error) { return p.Gossip(contentKeyHex, contentHex) } +func (p *API) BeaconPutContent(contentKeyHex, contentHex string) (*discover.PutContentResult, error) { + return p.PutContent(contentKeyHex, contentHex) +} + func (p *API) BeaconTraceGetContent(contentKeyHex string) (*discover.TraceContentResult, error) { return p.TraceRecursiveFindContent(contentKeyHex) } diff --git a/portalnetwork/history/api.go b/portalnetwork/history/api.go index bafdb4ea7a6f..e2b2b4fad1bf 100644 --- a/portalnetwork/history/api.go +++ b/portalnetwork/history/api.go @@ -60,10 +60,15 @@ func (p *API) HistoryStore(contentKeyHex string, contextHex string) (bool, error return p.Store(contentKeyHex, contextHex) } +// deprecated, use HistoryPutContent instead func (p *API) HistoryGossip(contentKeyHex, contentHex string) (int, error) { return p.Gossip(contentKeyHex, contentHex) } +func (p *API) HistoryPutContent(contentKeyHex, contentHex string) (*discover.PutContentResult, error) { + return p.PutContent(contentKeyHex, contentHex) +} + func (p *API) HistoryTraceGetContent(contentKeyHex string) (*discover.TraceContentResult, error) { return p.TraceRecursiveFindContent(contentKeyHex) } diff --git a/portalnetwork/state/api.go b/portalnetwork/state/api.go index 87afdf73b92f..c08ca67f3afa 100644 --- a/portalnetwork/state/api.go +++ b/portalnetwork/state/api.go @@ -60,10 +60,15 @@ func (p *API) StateStore(contentKeyHex string, contextHex string) (bool, error) return p.Store(contentKeyHex, contextHex) } +// deprecated, use StatePutContent instead func (p *API) StateGossip(contentKeyHex, contentHex string) (int, error) { return p.Gossip(contentKeyHex, contentHex) } +func (p *API) StatePutContent(contentKeyHex, contentHex string) (*discover.PutContentResult, error) { + return p.PutContent(contentKeyHex, contentHex) +} + func (p *API) StateTraceGetContent(contentKeyHex string) (*discover.TraceContentResult, error) { return p.TraceRecursiveFindContent(contentKeyHex) }