Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix deletion of host sectors #1762

Merged
merged 6 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
default: patch
---

# Fix DeleteHostSector deleting a sector from all hosts rather than the given one
2 changes: 1 addition & 1 deletion internal/test/e2e/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,7 @@ func addStorageFolderToHost(ctx context.Context, hosts []*Host) error {
// the group
func announceHosts(hosts []*Host) error {
for _, host := range hosts {
settings := defaultHostSettings
settings := host.settings.Settings()
settings.NetAddress = host.rhp4Listener.Addr().(*net.TCPAddr).IP.String()
if err := host.UpdateSettings(settings); err != nil {
return err
Expand Down
24 changes: 24 additions & 0 deletions internal/test/e2e/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1721,6 +1721,30 @@ func TestUploadPacking(t *testing.T) {
} else if res.Objects[1].Key != "/file2" {
t.Fatal("expected file2", res.Objects[1].Key)
}

// sanity check object metadata
assertObjectMetadata := func(key string) {
t.Helper()
obj, err := b.Object(context.Background(), testBucket, key, api.GetObjectOptions{})
tt.OK(err)
for _, slab := range obj.Slabs {
if len(slab.Shards) != 3 {
t.Fatalf("unexpected number of shards")
}
for _, shard := range slab.Shards {
if len(shard.Contracts) != 1 {
t.Fatalf("unexpected number of hosts in contracts map")
}
for _, fcids := range shard.Contracts {
if len(fcids) != 1 {
t.Fatalf("unexpected number of contracts")
}
}
}
}
}
assertObjectMetadata("/file1")
assertObjectMetadata("/file2")
}

func TestWallet(t *testing.T) {
Expand Down
21 changes: 16 additions & 5 deletions internal/test/e2e/gouging_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,20 @@ func TestGouging(t *testing.T) {
w := cluster.Worker
tt := cluster.tt

// add hosts
// add hosts with short price table validity to speed up test
gs, err := b.GougingSettings(context.Background())
tt.OK(err)
gs.MinPriceTableValidity = api.DurationMS(10 * time.Second)
tt.OK(cluster.bs.UpdateGougingSettings(context.Background(), gs))

n := int(test.AutopilotConfig.Contracts.Amount)
tt.OKAll(cluster.AddHostsBlocking(n))
for i := 0; i < n; i++ {
h := cluster.NewHost()
settings := h.settings.Settings()
settings.PriceTableValidity = time.Duration(gs.MinPriceTableValidity)
h.UpdateSettings(settings)
cluster.AddHost(h)
}
cluster.WaitForAccounts()

// assert all hosts are usable
Expand Down Expand Up @@ -66,21 +77,21 @@ func TestGouging(t *testing.T) {
tt.OK(cluster.hosts[0].UpdateSettings(updated))

// update gouging settings
gs := test.GougingSettings
gs = test.GougingSettings
gs.MaxStoragePrice = settings.StoragePrice
if err := b.UpdateGougingSettings(context.Background(), gs); err != nil {
t.Fatal(err)
}

// make sure the price table expires so the worker is forced to fetch it
// again, this is necessary for the host to be considered price gouging
time.Sleep(defaultHostSettings.PriceTableValidity)
time.Sleep(time.Duration(gs.MinPriceTableValidity))

// assert all but one host are usable
h, err = b.UsableHosts(context.Background())
tt.OK(err)
if len(h) != n-1 {
t.Fatal("unexpected number of hosts", len(h))
t.Fatal("unexpected number of hosts", len(h), n-1)
}

// upload some data - should fail
Expand Down
1 change: 1 addition & 0 deletions internal/test/e2e/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ func NewHost(privKey types.PrivateKey, cm *chain.Manager, dir string, network *c
settings.WithRHP2Port(uint16(rhp2Listener.Addr().(*net.TCPAddr).Port)),
settings.WithRHP3Port(uint16(rhp3Listener.Addr().(*net.TCPAddr).Port)),
settings.WithRHP4Port(uint16(rhp4Listener.Addr().(*net.TCPAddr).Port)),
settings.WithInitialSettings(defaultHostSettings),
)
if err != nil {
return nil, fmt.Errorf("failed to create settings manager: %w", err)
Expand Down
18 changes: 16 additions & 2 deletions stores/metadata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3428,6 +3428,7 @@ func TestDeleteHostSector(t *testing.T) {
if err != nil {
t.Fatal(err)
}
hk1FCIDs, hk2FCIDs := fcids[:2], fcids[2:]

// create a healthy slab with one sector that is uploaded to all contracts.
root := types.Hash256{1, 2, 3}
Expand All @@ -3436,8 +3437,11 @@ func TestDeleteHostSector(t *testing.T) {
MinShards: 1,
Shards: []object.Sector{
{
Contracts: map[types.PublicKey][]types.FileContractID{hk1: fcids},
Root: root,
Contracts: map[types.PublicKey][]types.FileContractID{
hk1: hk1FCIDs,
hk2: hk2FCIDs,
},
Root: root,
},
},
})
Expand All @@ -3447,6 +3451,11 @@ func TestDeleteHostSector(t *testing.T) {
t.Fatal("expected 4 contract-sector links", n)
}

// Make sure 2 hostSector entries exist.
if n := ss.Count("host_sectors"); n != 2 {
t.Fatal("expected 2 host-sector links", n)
}

// Prune the sector from hk1.
if n, err := ss.DeleteHostSector(context.Background(), hk1, root); err != nil {
t.Fatal(err)
Expand All @@ -3459,6 +3468,11 @@ func TestDeleteHostSector(t *testing.T) {
t.Fatal("expected 2 contract-sector links", n)
}

// Make sure 1 hostSector entry exists.
if n := ss.Count("host_sectors"); n != 1 {
t.Fatal("expected 1 host-sector link", n)
}

// Find the slab. It should have an invalid health.
var slabID int64
var validUntil int64
Expand Down
34 changes: 20 additions & 14 deletions stores/sql/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,14 @@ func DeleteHostSector(ctx context.Context, tx sql.Tx, hk types.PublicKey, root t
}

// remove sector from host_sectors
_, err = tx.Exec(ctx, "DELETE FROM host_sectors WHERE db_sector_id = ?", sectorID)
_, err = tx.Exec(ctx, `
DELETE FROM host_sectors
WHERE db_sector_id = ? AND db_host_id IN (
SELECT h.id
FROM hosts h
WHERE h.public_key = ?
)
`, sectorID, PublicKey(hk))
if err != nil {
return 0, fmt.Errorf("failed to delete host sector: %w", err)
}
Expand Down Expand Up @@ -2479,7 +2486,7 @@ func MarkPackedSlabUploaded(ctx context.Context, tx Tx, slab api.UploadedPackedS
defer hostSectorStmt.Close()

// insert shards
for i := range slab.Shards {
for i, sector := range slab.Shards {
// insert shard
res, err := sectorStmt.Exec(ctx, slabID, i+1, slab.Shards[i].Root[:])
if err != nil {
Expand All @@ -2490,20 +2497,19 @@ func MarkPackedSlabUploaded(ctx context.Context, tx Tx, slab api.UploadedPackedS
return "", fmt.Errorf("failed to get sector id: %w", err)
}

// insert contract sector links
for _, sector := range slab.Shards {
uc, ok := usedContracts[sector.ContractID]
if !ok {
continue
}
uc, ok := usedContracts[sector.ContractID]
if !ok {
continue
}

if _, err := contractSectorStmt.Exec(ctx, uc.ID, sectorID); err != nil {
return "", fmt.Errorf("failed to insert contract sector: %w", err)
}
// insert contract sector links
if _, err := contractSectorStmt.Exec(ctx, uc.ID, sectorID); err != nil {
return "", fmt.Errorf("failed to insert contract sector: %w", err)
}

if _, err := hostSectorStmt.Exec(ctx, uc.HostID, sectorID); err != nil {
return "", fmt.Errorf("failed to insert host sector: %w", err)
}
// insert host sector link
if _, err := hostSectorStmt.Exec(ctx, uc.HostID, sectorID); err != nil {
return "", fmt.Errorf("failed to insert host sector: %w", err)
}
}
return bufferFileName, nil
Expand Down
Loading