Skip to content

Commit

Permalink
feat(nodebuilder/header): Bootstrap from previously seen peers (#2507)
Browse files Browse the repository at this point in the history
Provides `PIDStore` to header module so that it can be used in
`peerTracker` and replaces mem `peerstore.Peerstore` with on-disk
`peerstore.Peerstore` so that `peerTracker` can quickly bootstrap itself
with previously-seen peers and allow syncer to initialise its sync
target from tracked peers rather than trusted so long as it has a
subjective head within the trusting period.

Overrides #2133 

Closes #1851, mitigates issues resulting from #1623

Swamp integration tests to follow (tracked in #2506)

### Future note: 

This PR introduces a soon-to-be deprecated feature from libp2p (on-disk
peerstore). Once libp2p deprecates and removes this feature, the
PIDStore will have to become a PeerAddrStore such that it can save addr
info of good peers to disk instead of just their IDs.
  • Loading branch information
renaynay authored Sep 5, 2023
1 parent 96388ea commit c146a0a
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 9 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ require (
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-safetemp v1.0.0 // indirect
github.com/hashicorp/go-version v1.6.0 // indirect
github.com/hashicorp/golang-lru/arc/v2 v2.0.5 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.5 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 // indirect
Expand Down
5 changes: 5 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ github.com/99designs/keyring v1.2.1 h1:tYLp1ULvO7i3fI5vE21ReQuj99QFSs7lGm0xWyJo8
github.com/99designs/keyring v1.2.1/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA=
github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIoKjsnZuH8vjyaysT/ses3EvZeaV/1UkF2M=
github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1/go.mod h1:fBF9PQNqB8scdgpZ3ufzaLntG0AG7C1WjPMsiFOmfHM=
github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.3/go.mod h1:KLF4gFr6DcKFZwSuH8w8yEK6DpFl3LP5rhdvAb7Yz5I=
Expand Down Expand Up @@ -535,6 +536,7 @@ github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzA
github.com/dgraph-io/badger v1.6.0-rc1/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4=
github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4=
github.com/dgraph-io/badger v1.6.1/go.mod h1:FRmFw3uxvcpa8zG3Rxs0th+hCLIuaQg8HlNV5bjgnuU=
github.com/dgraph-io/badger v1.6.2 h1:mNw0qs90GVgGGWylh0umH5iag1j6n/PeJtNvL6KY/x8=
github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE=
github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o=
github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk=
Expand Down Expand Up @@ -965,6 +967,8 @@ github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uG
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/golang-lru/arc/v2 v2.0.5 h1:l2zaLDubNhW4XO3LnliVj0GXO3+/CGNJAg1dcN2Fpfw=
github.com/hashicorp/golang-lru/arc/v2 v2.0.5/go.mod h1:ny6zBSQZi2JxIeYcv7kt2sH2PXJtirBN7RDhRpxPkxU=
github.com/hashicorp/golang-lru/v2 v2.0.1/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/hashicorp/golang-lru/v2 v2.0.5 h1:wW7h1TG88eUIJ2i69gaE3uNVtEPIagzhGvHgwfx2Vm4=
github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
Expand Down Expand Up @@ -1081,6 +1085,7 @@ github.com/ipfs/go-ds-badger v0.0.5/go.mod h1:g5AuuCGmr7efyzQhLL8MzwqcauPojGPUaH
github.com/ipfs/go-ds-badger v0.0.7/go.mod h1:qt0/fWzZDoPW6jpQeqUjR5kBfhDNB65jd9YlmAvpQBk=
github.com/ipfs/go-ds-badger v0.2.1/go.mod h1:Tx7l3aTph3FMFrRS838dcSJh+jjA7cX9DrGVwx/NOwE=
github.com/ipfs/go-ds-badger v0.2.3/go.mod h1:pEYw0rgg3FIrywKKnL+Snr+w/LjJZVMTBRn4FS6UHUk=
github.com/ipfs/go-ds-badger v0.3.0 h1:xREL3V0EH9S219kFFueOYJJTcjgNSZ2HY1iSvN7U1Ro=
github.com/ipfs/go-ds-badger v0.3.0/go.mod h1:1ke6mXNqeV8K3y5Ak2bAA0osoTfmxUdupVCGm4QUIek=
github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc=
github.com/ipfs/go-ds-leveldb v0.1.0/go.mod h1:hqAW8y4bwX5LWcCtku2rFNX3vjDZCy5LZCg+cSZvYb8=
Expand Down
14 changes: 12 additions & 2 deletions libs/pidstore/pidstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,20 @@ type PeerIDStore struct {
}

// NewPeerIDStore creates a new peer ID store backed by the given datastore.
func NewPeerIDStore(ds datastore.Datastore) *PeerIDStore {
return &PeerIDStore{
func NewPeerIDStore(ctx context.Context, ds datastore.Datastore) (*PeerIDStore, error) {
pidstore := &PeerIDStore{
ds: namespace.Wrap(ds, storePrefix),
}
// check if pidstore is already initialized, and if not,
// initialize the pidstore
exists, err := pidstore.ds.Has(ctx, peersKey)
if err != nil {
return nil, err
}
if !exists {
return pidstore, pidstore.Put(ctx, []peer.ID{})
}
return pidstore, nil
}

// Load loads the peers from datastore and returns them.
Expand Down
14 changes: 13 additions & 1 deletion libs/pidstore/pidstore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,19 @@ func TestPutLoad(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer t.Cleanup(cancel)

peerstore := NewPeerIDStore(sync.MutexWrap(datastore.NewMapDatastore()))
ds := sync.MutexWrap(datastore.NewMapDatastore())

t.Run("unitialized-pidstore", func(t *testing.T) {
testPutLoad(ctx, ds, t)
})
t.Run("initialized-pidstore", func(t *testing.T) {
testPutLoad(ctx, ds, t)
})
}

func testPutLoad(ctx context.Context, ds datastore.Datastore, t *testing.T) {
peerstore, err := NewPeerIDStore(ctx, ds)
require.NoError(t, err)

ids, err := generateRandomPeerList(10)
require.NoError(t, err)
Expand Down
5 changes: 3 additions & 2 deletions nodebuilder/header/constructors.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@ import (
// newP2PExchange constructs a new Exchange for headers.
func newP2PExchange[H libhead.Header[H]](
lc fx.Lifecycle,
cfg Config,
bpeers modp2p.Bootstrappers,
network modp2p.Network,
host host.Host,
conngater *conngater.BasicConnectionGater,
cfg Config,
pidstore p2p.PeerIDStore,
) (libhead.Exchange[H], error) {
peers, err := cfg.trustedPeers(bpeers)
if err != nil {
Expand All @@ -42,6 +43,7 @@ func newP2PExchange[H libhead.Header[H]](
p2p.WithParams(cfg.Client),
p2p.WithNetworkID[p2p.ClientParameters](network.String()),
p2p.WithChainID(network.String()),
p2p.WithPeerIDStore[p2p.ClientParameters](pidstore),
)
if err != nil {
return nil, err
Expand All @@ -55,7 +57,6 @@ func newP2PExchange[H libhead.Header[H]](
},
})
return exchange, nil

}

// newSyncer constructs new Syncer for headers.
Expand Down
4 changes: 4 additions & 0 deletions nodebuilder/header/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/celestiaorg/go-header/sync"

"github.com/celestiaorg/celestia-node/header"
"github.com/celestiaorg/celestia-node/libs/pidstore"
modfraud "github.com/celestiaorg/celestia-node/nodebuilder/fraud"
"github.com/celestiaorg/celestia-node/nodebuilder/node"
modp2p "github.com/celestiaorg/celestia-node/nodebuilder/p2p"
Expand Down Expand Up @@ -99,6 +100,9 @@ func ConstructModule[H libhead.Header[H]](tp node.Type, cfg *Config) fx.Option {
"header",
baseComponents,
fx.Provide(newP2PExchange[H]),
fx.Provide(func(ctx context.Context, ds datastore.Batching) (p2p.PeerIDStore, error) {
return pidstore.NewPeerIDStore(ctx, ds)
}),
)
case node.Bridge:
return fx.Module(
Expand Down
3 changes: 3 additions & 0 deletions nodebuilder/header/module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/celestiaorg/go-header/sync"

"github.com/celestiaorg/celestia-node/header"
"github.com/celestiaorg/celestia-node/libs/pidstore"
"github.com/celestiaorg/celestia-node/nodebuilder/node"
modp2p "github.com/celestiaorg/celestia-node/nodebuilder/p2p"
)
Expand Down Expand Up @@ -94,6 +95,8 @@ func TestConstructModule_ExchangeParams(t *testing.T) {
var exchangeServer *p2p.ExchangeServer[*header.ExtendedHeader]

app := fxtest.New(t,
fx.Provide(pidstore.NewPeerIDStore),
fx.Provide(context.Background),
fx.Supply(modp2p.Private),
fx.Supply(modp2p.Bootstrappers{}),
fx.Provide(libp2p.New),
Expand Down
9 changes: 5 additions & 4 deletions nodebuilder/p2p/misc.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package p2p

import (
"context"
"time"

"github.com/ipfs/go-datastore"
connmgri "github.com/libp2p/go-libp2p/core/connmgr"
"github.com/libp2p/go-libp2p/core/peerstore"
"github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem"
"github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoreds" //nolint:staticcheck
"github.com/libp2p/go-libp2p/p2p/net/conngater"
"github.com/libp2p/go-libp2p/p2p/net/connmgr"

Expand Down Expand Up @@ -71,7 +72,7 @@ func connectionGater(ds datastore.Batching) (*conngater.BasicConnectionGater, er
return conngater.NewBasicConnectionGater(ds)
}

// peerStore constructs a PeerStore.
func peerStore() (peerstore.Peerstore, error) {
return pstoremem.NewPeerstore()
// peerStore constructs an on-disk PeerStore.
func peerStore(ctx context.Context, ds datastore.Batching) (peerstore.Peerstore, error) {
return pstoreds.NewPeerstore(ctx, ds, pstoreds.DefaultOpts())
}

0 comments on commit c146a0a

Please sign in to comment.