Skip to content

Commit 2412aa6

Browse files
LexLuthrdirkmcnonsense
authored
feat: add multi-miner to single LID support (#1656)
* feat: retrieve data served from multiple miners (#1578) * add booster-http multi-miner retrieve test (#1598) * feat: add booster-http multi-miner retrieve test * refactor: move api version check to its own function * test: add booster-bitswap multi-miner test (#1599) * multi-miner / single LID - piece doctor (#1600) * wip: multi-miner / 1 LID - piece doctor * refactor: move yugabyte migration details into a separate class * fix: add miner address to yugabyte / leveldb impl * refactor: update log in piece doctor no deals for miner to warning * refactor: break migration into two parts to avoid migrations bug * feat: skip set address in migration if PieceTracker table has no rows (#1614) * fix: split PieceTracker and PieceFlagged migrations (#1615) * fix: yugabyte migrate command name * Add miner address to top of page in boost UI (#1633) * feat: add miner address to top of page in boost UI * Update react/src/MinerAddress.js Co-authored-by: LexLuthr <[email protected]> --------- Co-authored-by: LexLuthr <[email protected]> * refactor: move StorageAccessApiInfo config into DealMaking at GraphsyncStorageAccessApiInfo (#1634) * Show list of retrieval miners on retrievals list page (#1637) * feat: show list of retrieval miners on retrievals list page * fix: retrieval miner address resolver * fix: mmlid fixes for LID UI (#1639) * fix: look up unseal status against multi-miner accessor (rather than just on local miner) (#1641) * Show warning on piece doctor page if still doing initial scan (#1643) * fix: look up unseal status against multi-miner accessor (rather than just on local miner) * feat: show warning on piece doctor page if still doing initial scan * Update extern/boostd-data/yugabyte/piecedoctor.go Co-authored-by: Anton Evangelatov <[email protected]> * Update extern/boostd-data/yugabyte/piecedoctor.go --------- Co-authored-by: Anton Evangelatov <[email protected]> * feat: change postgres timezone type to include timezone (#1645) * feat: show network name in binary versions (#1642) * fix boostd-data maddr, enhance build * add CQL migrator * refactor migrator * modify migrate query * remove idx from migrate query * remove CQL migrator * undo go mod changes, fix mainnet build * undo yugabyte changes * remove extra line * Cassandra migrations (#1648) * feat: cassandra migrations * refactor: dbname -> appliedMigration * fix: yugabyte lid test * feat: add postgres migration * refactor: simplify cassandra migrations * fix: delete duplicate rows in PieceTracker table * fix test --------- Co-authored-by: dirkmc <[email protected]> Co-authored-by: Anton Evangelatov <[email protected]>
1 parent 4ce0c4b commit 2412aa6

File tree

106 files changed

+3082
-1341
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

106 files changed

+3082
-1341
lines changed

.circleci/config.yml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,12 +344,27 @@ workflows:
344344
- test:
345345
name: test-all
346346
suite: all
347-
target: "`go list ./... | grep -v boost/itests`"
347+
target: "`go list ./... | grep -v boost/itests | grep -v cmd/booster-http | grep -v cmd/booster-bitswap`"
348348

349349
- test:
350350
name: test-itest-ipni
351351
suite: itest-ipni
352352
target: "./itests/ipni_publish_test.go"
353353

354+
- test:
355+
name: test-itest-multiminer-graphsync
356+
suite: itest-multiminer-graphsync
357+
target: "./itests/multiminer_retrieval_graphsync_test.go"
358+
359+
- test:
360+
name: test-booster-http
361+
suite: booster-http
362+
target: "./cmd/booster-http"
363+
364+
- test:
365+
name: test-booster-bitswap
366+
suite: booster-bitswap
367+
target: "./cmd/booster-bitswap"
368+
354369
- lid-docker-compose
355370

build/params_calibnet.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//go:build calibnet
2+
// +build calibnet
3+
4+
package build
5+
6+
import (
7+
"github.com/filecoin-project/go-address"
8+
)
9+
10+
func init() {
11+
SetAddressNetwork(address.Testnet)
12+
BuildType = BuildCalibnet
13+
}

build/params_mainnet.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//go:build !calibnet && !debug && !2k
2+
// +build !calibnet,!debug,!2k
3+
4+
package build
5+
6+
import (
7+
"github.com/filecoin-project/go-address"
8+
)
9+
10+
func init() {
11+
SetAddressNetwork(address.Mainnet)
12+
BuildType = BuildMainnet
13+
}

build/params_testnets.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//go:build debug || 2k
2+
// +build debug 2k
3+
4+
package build
5+
6+
import (
7+
"github.com/filecoin-project/go-address"
8+
)
9+
10+
func init() {
11+
SetAddressNetwork(address.Testnet)
12+
BuildType = BuildDebug
13+
}

build/version.go

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,38 @@
11
package build
22

33
var CurrentCommit string
4+
var BuildType int
5+
6+
const (
7+
BuildMainnet = 0x1
8+
Build2k = 0x2
9+
BuildDebug = 0x3
10+
BuildCalibnet = 0x4
11+
BuildInteropnet = 0x5
12+
BuildButterflynet = 0x7
13+
)
14+
15+
func BuildTypeString() string {
16+
switch BuildType {
17+
case BuildMainnet:
18+
return "+mainnet"
19+
case Build2k:
20+
return "+2k"
21+
case BuildDebug:
22+
return "+debug"
23+
case BuildCalibnet:
24+
return "+calibnet"
25+
case BuildInteropnet:
26+
return "+interopnet"
27+
case BuildButterflynet:
28+
return "+butterflynet"
29+
default:
30+
return "+huh?"
31+
}
32+
}
433

534
const BuildVersion = "2.0.0-rc1"
635

736
func UserVersion() string {
8-
return BuildVersion + CurrentCommit
37+
return BuildVersion + BuildTypeString() + CurrentCommit
938
}

cmd/boostd/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ func before(cctx *cli.Context) error {
7373
_ = logging.SetLogLevel("piecedoc", "INFO")
7474
_ = logging.SetLogLevel("piecedirectory", "INFO")
7575
_ = logging.SetLogLevel("sectorstatemgr", "INFO")
76+
_ = logging.SetLogLevel("migrations", "INFO")
7677

7778
if cliutil.IsVeryVerbose {
7879
_ = logging.SetLogLevel("boostd", "DEBUG")

cmd/boostd/recover.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,11 @@ func action(cctx *cli.Context) error {
170170
}
171171
defer ncloser()
172172

173+
err = lib.CheckFullNodeApiVersion(ctx, fullnodeApi)
174+
if err != nil {
175+
return err
176+
}
177+
173178
// Connect to the storage API and create a sector accessor
174179
storageApiInfo := cctx.String("api-storage")
175180

cmd/booster-bitswap/client.go

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/ipld/go-ipld-prime"
1414
cidlink "github.com/ipld/go-ipld-prime/linking/cid"
1515
"github.com/ipld/go-ipld-prime/traversal"
16+
"github.com/libp2p/go-libp2p/core/host"
1617
mh "github.com/multiformats/go-multihash"
1718

1819
"github.com/filecoin-project/boost/cmd/booster-bitswap/bitswap"
@@ -90,14 +91,7 @@ var fetchCmd = &cli.Command{
9091
return err
9192
}
9293

93-
host, err := libp2p.New(
94-
libp2p.Transport(tcp.NewTCPTransport),
95-
libp2p.Transport(quic.NewTransport),
96-
libp2p.Muxer("/mplex/6.7.0", mplex.DefaultTransport),
97-
libp2p.Muxer("/yamux/1.0.0", yamux.DefaultTransport),
98-
libp2p.Identity(privKey),
99-
libp2p.ResourceManager(&network.NullResourceManager{}),
100-
)
94+
host, err := createClientHost(privKey)
10195
if err != nil {
10296
return err
10397
}
@@ -169,6 +163,17 @@ var fetchCmd = &cli.Command{
169163
},
170164
}
171165

166+
func createClientHost(privKey crypto.PrivKey) (host.Host, error) {
167+
return libp2p.New(
168+
libp2p.Transport(tcp.NewTCPTransport),
169+
libp2p.Transport(quic.NewTransport),
170+
libp2p.Muxer("/mplex/6.7.0", mplex.DefaultTransport),
171+
libp2p.Muxer("/yamux/1.0.0", yamux.DefaultTransport),
172+
libp2p.Identity(privKey),
173+
libp2p.ResourceManager(&network.NullResourceManager{}),
174+
)
175+
}
176+
172177
func getBlocks(ctx context.Context, bsClient *client.Client, c cid.Cid, throttle chan struct{}) (uint64, uint64, error) {
173178
var size uint64
174179
var links []cid.Cid

cmd/booster-bitswap/main.go

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,23 @@ var FlagRepo = &cli.StringFlag{
1818
EnvVars: []string{"BOOSTER_BITSWAP_REPO"},
1919
}
2020

21+
var app = &cli.App{
22+
Name: "booster-bitswap",
23+
Usage: "Bitswap endpoint for retrieval from Filecoin",
24+
EnableBashCompletion: true,
25+
Version: build.UserVersion(),
26+
Flags: []cli.Flag{
27+
cliutil.FlagVeryVerbose,
28+
FlagRepo,
29+
},
30+
Commands: []*cli.Command{
31+
initCmd,
32+
runCmd,
33+
fetchCmd,
34+
},
35+
}
36+
2137
func main() {
22-
app := &cli.App{
23-
Name: "booster-bitswap",
24-
Usage: "Bitswap endpoint for retrieval from Filecoin",
25-
EnableBashCompletion: true,
26-
Version: build.UserVersion(),
27-
Flags: []cli.Flag{
28-
cliutil.FlagVeryVerbose,
29-
FlagRepo,
30-
},
31-
Commands: []*cli.Command{
32-
initCmd,
33-
runCmd,
34-
fetchCmd,
35-
},
36-
}
3738
app.Setup()
3839

3940
if err := app.Run(os.Args); err != nil {
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"crypto/rand"
6+
"fmt"
7+
"github.com/filecoin-project/boost/cmd/booster-bitswap/bitswap"
8+
"github.com/filecoin-project/boost/itests/shared"
9+
carv2 "github.com/ipld/go-car/v2"
10+
"github.com/libp2p/go-libp2p/core/crypto"
11+
"github.com/libp2p/go-libp2p/core/host"
12+
"github.com/libp2p/go-libp2p/core/peer"
13+
"github.com/multiformats/go-multiaddr"
14+
"github.com/stretchr/testify/require"
15+
"path"
16+
"sort"
17+
"testing"
18+
"time"
19+
)
20+
21+
func TestMultiMinerBitswapRetrieval(t *testing.T) {
22+
shared.RunMultiminerRetrievalTest(t, func(ctx context.Context, t *testing.T, rt *shared.RetrievalTest) {
23+
miner1ApiInfo, err := rt.BoostAndMiner1.LotusMinerApiInfo()
24+
require.NoError(t, err)
25+
26+
miner2ApiInfo, err := rt.BoostAndMiner2.LotusMinerApiInfo()
27+
require.NoError(t, err)
28+
29+
fullNode2ApiInfo, err := rt.BoostAndMiner2.LotusFullNodeApiInfo()
30+
require.NoError(t, err)
31+
32+
repoDir := t.TempDir()
33+
peerID, _, err := configureRepo(repoDir, true)
34+
require.NoError(t, err)
35+
36+
runCtx, cancelRun := context.WithCancel(ctx)
37+
defer cancelRun()
38+
39+
go func() {
40+
// Configure booster-bitswap to
41+
// - Get piece location information from the shared LID instance
42+
// - Get the piece data from either miner1 or miner2 (depending on the location info)
43+
apiInfo := []string{miner1ApiInfo, miner2ApiInfo}
44+
_ = runBoosterBitswap(runCtx, repoDir, apiInfo, fullNode2ApiInfo, "ws://localhost:8042")
45+
}()
46+
47+
maddr, err := multiaddr.NewMultiaddr("/ip4/127.0.0.1/tcp/8888")
48+
require.NoError(t, err)
49+
50+
privKey, _, err := crypto.GenerateECDSAKeyPair(rand.Reader)
51+
require.NoError(t, err)
52+
53+
clientHost, err := createClientHost(privKey)
54+
require.NoError(t, err)
55+
56+
t.Logf("waiting for server to come up")
57+
start := time.Now()
58+
require.Eventually(t, func() bool {
59+
err := connectToHost(ctx, clientHost, maddr, peerID)
60+
if err != nil {
61+
t.Logf("connecting to host: %s", err)
62+
return false
63+
}
64+
return true
65+
}, 30*time.Second, time.Second)
66+
t.Logf("booster-bitswap is up after %s", time.Since(start))
67+
68+
outPath := path.Join(t.TempDir(), "out.dat")
69+
fetchAddr := maddr.String() + "/p2p/" + peerID.String()
70+
err = runBoosterBitswapFetch(ctx, fetchAddr, rt.RootCid.String(), outPath)
71+
require.NoError(t, err)
72+
73+
t.Logf("retrieval is done, compare root cid %s to downloaded CAR root cid", rt.RootCid)
74+
r, err := carv2.OpenReader(outPath)
75+
require.NoError(t, err)
76+
77+
roots, err := r.Roots()
78+
require.NoError(t, err)
79+
require.Len(t, roots, 1)
80+
require.Equal(t, rt.RootCid, roots[0])
81+
82+
t.Logf("file retrieved successfully")
83+
})
84+
}
85+
86+
func connectToHost(ctx context.Context, clientHost host.Host, maddr multiaddr.Multiaddr, pid peer.ID) error {
87+
// Connect to host
88+
err := clientHost.Connect(ctx, peer.AddrInfo{
89+
ID: pid,
90+
Addrs: []multiaddr.Multiaddr{maddr},
91+
})
92+
if err != nil {
93+
return err
94+
}
95+
96+
// Check host's libp2p protocols
97+
protos, err := clientHost.Peerstore().GetProtocols(pid)
98+
if err != nil {
99+
return fmt.Errorf("getting protocols from peer store for %s: %w", pid, err)
100+
}
101+
sort.Slice(protos, func(i, j int) bool {
102+
return protos[i] < protos[j]
103+
})
104+
fmt.Println("host libp2p protocols", "protocols", protos)
105+
p, err := clientHost.Peerstore().FirstSupportedProtocol(pid, bitswap.Protocols...)
106+
if err != nil {
107+
return fmt.Errorf("getting first supported protocol from peer store for %s: %w", pid, err)
108+
}
109+
if p == "" {
110+
return fmt.Errorf("host %s does not support any know bitswap protocols: %s", pid, bitswap.ProtocolStrings)
111+
}
112+
return nil
113+
}
114+
115+
func runBoosterBitswap(ctx context.Context, repo string, minerApiInfo []string, fullNodeApiInfo string, lidApiInfo string) error {
116+
app.Setup()
117+
118+
args := []string{"booster-bitswap",
119+
"--repo=" + repo,
120+
"run",
121+
"--api-fullnode=" + fullNodeApiInfo,
122+
"--api-lid=" + lidApiInfo,
123+
"--api-version-check=false",
124+
}
125+
for _, apiInfo := range minerApiInfo {
126+
args = append(args, "--api-storage="+apiInfo)
127+
}
128+
return app.RunContext(ctx, args)
129+
}
130+
131+
func runBoosterBitswapFetch(ctx context.Context, multiaddr string, rootCid string, outputPath string) error {
132+
args := []string{"booster-bitswap", "fetch", multiaddr, rootCid, outputPath}
133+
return app.RunContext(ctx, args)
134+
}

0 commit comments

Comments
 (0)