forked from ethereum-optimism/optimism
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Metadata Store to Extended Peerstore
- Loading branch information
Axel Kingsley
authored and
Axel Kingsley
committed
Dec 14, 2023
1 parent
6e371b4
commit f5f57c1
Showing
6 changed files
with
151 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
package store | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"sync/atomic" | ||
"time" | ||
|
||
"github.com/ethereum-optimism/optimism/op-service/clock" | ||
"github.com/ethereum/go-ethereum/log" | ||
ds "github.com/ipfs/go-datastore" | ||
"github.com/libp2p/go-libp2p/core/peer" | ||
) | ||
|
||
const ( | ||
mdCacheSize = 100 | ||
mdRecordExpiration = time.Hour * 24 * 7 | ||
) | ||
|
||
var metadataBase = ds.NewKey("/peers/md") | ||
|
||
// LastUpdate requires atomic update operations. Use the helper functions SetLastUpdated and LastUpdated to modify and access this field. | ||
type metadataRecord struct { | ||
LastUpdate int64 `json:"lastUpdate"` // unix timestamp in seconds | ||
PeerMetadata PeerMetadata `json:"peerMetadata"` | ||
} | ||
|
||
type PeerMetadata struct { | ||
ENR string `json:"enr"` | ||
OPStackID uint64 `json:"opStackID"` | ||
} | ||
|
||
func (m *metadataRecord) SetLastUpdated(t time.Time) { | ||
atomic.StoreInt64(&m.LastUpdate, t.Unix()) | ||
} | ||
|
||
func (m *metadataRecord) LastUpdated() time.Time { | ||
return time.Unix(atomic.LoadInt64(&m.LastUpdate), 0) | ||
} | ||
|
||
func (m *metadataRecord) MarshalBinary() (data []byte, err error) { | ||
return json.Marshal(m) | ||
} | ||
|
||
func (m *metadataRecord) UnmarshalBinary(data []byte) error { | ||
return json.Unmarshal(data, m) | ||
} | ||
|
||
type metadataBook struct { | ||
book *recordsBook[peer.ID, *metadataRecord] | ||
} | ||
|
||
func newMetadataRecord() *metadataRecord { | ||
return new(metadataRecord) | ||
} | ||
|
||
func newMetadataBook(ctx context.Context, logger log.Logger, clock clock.Clock, store ds.Batching) (*metadataBook, error) { | ||
book, err := newRecordsBook[peer.ID, *metadataRecord](ctx, logger, clock, store, mdCacheSize, mdRecordExpiration, metadataBase, newMetadataRecord, peerIDKey) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return &metadataBook{book: book}, nil | ||
} | ||
|
||
func (m *metadataBook) startGC() { | ||
m.book.startGC() | ||
} | ||
|
||
func (m *metadataBook) GetPeerMetadata(id peer.ID) (PeerMetadata, error) { | ||
record, err := m.book.getRecord(id) | ||
// If the record is not found, return an empty PeerMetadata | ||
if err == UnknownRecordErr { | ||
return PeerMetadata{}, nil | ||
} | ||
if err != nil { | ||
return PeerMetadata{}, err | ||
} | ||
return record.PeerMetadata, nil | ||
} | ||
|
||
// Apply simply overwrites the record with the new one. | ||
// presently, metadata is only collected during peering, so this is fine. | ||
// if in the future this data can be updated or expanded, this function will need to be updated. | ||
func (md *metadataRecord) Apply(rec *metadataRecord) { | ||
*rec = *md | ||
} | ||
|
||
func (m *metadataBook) SetPeerMetadata(id peer.ID, md PeerMetadata) (PeerMetadata, error) { | ||
rec := newMetadataRecord() | ||
rec.PeerMetadata = md | ||
rec.SetLastUpdated(m.book.clock.Now()) | ||
v, err := m.book.SetRecord(id, rec) | ||
return v.PeerMetadata, err | ||
} | ||
|
||
func (m *metadataBook) Close() { | ||
m.book.Close() | ||
} |