Skip to content

Commit

Permalink
extend test to check if number of contracts is right and if contracts…
Browse files Browse the repository at this point in the history
… are on right hosts
  • Loading branch information
ChrisSchinnerl committed Dec 13, 2024
1 parent 29b3b7a commit c20ce92
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 17 deletions.
16 changes: 11 additions & 5 deletions autopilot/contractor/contractor.go
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,9 @@ func activeContracts(ctx context.Context, bus Bus, logger *zap.SugaredLogger) ([
// fetch active contracts
logger.Info("fetching active contracts")
start := time.Now()
metadatas, err := bus.Contracts(ctx, api.ContractsOpts{FilterMode: api.ContractFilterModeActive})
metadatas, err := bus.Contracts(ctx, api.ContractsOpts{
FilterMode: api.ContractFilterModeActive,
})
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -902,7 +904,9 @@ func performContractFormations(ctx *mCtx, bus Bus, cr contractReviser, hf hostFi
wanted := int(ctx.WantedContracts())

// fetch all active contracts
contracts, err := bus.Contracts(ctx, api.ContractsOpts{})
contracts, err := bus.Contracts(ctx, api.ContractsOpts{
FilterMode: api.ContractFilterModeActive,
})
if err != nil {
return 0, fmt.Errorf("failed to fetch contracts: %w", err)
}
Expand Down Expand Up @@ -1052,7 +1056,9 @@ func performHostChecks(ctx *mCtx, bus Bus, logger *zap.SugaredLogger) error {

func performPostMaintenanceTasks(ctx *mCtx, bus Bus, alerter alerts.Alerter, cc contractChecker, rb revisionBroadcaster, logger *zap.SugaredLogger) error {
// fetch some contract and host info
allContracts, err := bus.Contracts(ctx, api.ContractsOpts{})
allContracts, err := bus.Contracts(ctx, api.ContractsOpts{
FilterMode: api.ContractFilterModeActive,
})
if err != nil {
return fmt.Errorf("failed to fetch all contracts: %w", err)
}
Expand Down Expand Up @@ -1117,7 +1123,7 @@ func performV2ContractMigration(ctx *mCtx, bus Bus, cr contractReviser, logger *
}

contracts, err := bus.Contracts(ctx, api.ContractsOpts{
FilterMode: api.ContractFilterModeAll, // TODO: change to usable
FilterMode: api.ContractFilterModeActive,
})
if err != nil {
logger.With(zap.Error(err)).Error("failed to fetch contracts for migration")
Expand Down Expand Up @@ -1149,7 +1155,7 @@ func performV2ContractMigration(ctx *mCtx, bus Bus, cr contractReviser, logger *
}

// form a new contract with the same host
contract, _, err := cr.formContract(ctx, bus, host, InitialContractFunding, logger)
_, _, err = cr.formContract(ctx, bus, host, InitialContractFunding, logger)
if err != nil {
logger.Errorf("failed to form a v2 contract with the host")
continue
Expand Down
7 changes: 6 additions & 1 deletion autopilot/contractor/hostfilter.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"go.sia.tech/core/types"
"go.sia.tech/renterd/api"
"go.sia.tech/renterd/internal/gouging"
rhp4 "go.sia.tech/renterd/internal/rhp/v4"
)

const (
Expand Down Expand Up @@ -165,7 +166,11 @@ func checkHost(gc gouging.Checker, sh scoredHost, minScore float64, period uint6
// calculate remaining host info fields
if !h.IsAnnounced() {
ub.NotAnnounced = true
} else if !h.Scanned {
} else if !h.Scanned ||
// NOTE: a v2 host might have been scanned before the v2 height so strictly
// speaking it is scanned but since it hasn't been scanned since, the
// settings aren't set so we treat it as not scanned
(h.IsV2() && h.V2Settings == (rhp4.HostSettings{})) {
ub.NotCompletingScan = true
} else {
// online check
Expand Down
7 changes: 7 additions & 0 deletions bus/bus.go
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,13 @@ func (b *Bus) renewContractV1(ctx context.Context, cs consensus.State, gp api.Go
// derive the renter key
renterKey := b.masterKey.DeriveContractKey(c.HostKey)

// cap v1 renewals to the v2 require height since the host won't allow us to
// form contracts beyond that
v2ReqHeight := b.cm.TipState().Network.HardforkV2.RequireHeight
if endHeight >= v2ReqHeight {
endHeight = v2ReqHeight - 1
}

// fetch the revision
rev, err := b.rhp3Client.Revision(ctx, c.ID, c.HostKey, hs.SiamuxAddr())
if err != nil {
Expand Down
7 changes: 7 additions & 0 deletions bus/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -2320,6 +2320,13 @@ func (b *Bus) contractsFormHandler(jc jape.Context) {
return
}

// cap v1 formations to the v2 require height since the host won't allow
// us to form contracts beyond that
v2ReqHeight := b.cm.TipState().Network.HardforkV2.RequireHeight
if rfr.EndHeight >= v2ReqHeight {
rfr.EndHeight = v2ReqHeight - 1
}

// check gouging
breakdown := gc.CheckSettings(settings)
if breakdown.Gouging() {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ require (
go.sia.tech/core v0.7.2-0.20241210224920-0534a5928ddb
go.sia.tech/coreutils v0.7.1-0.20241211045514-6881993d8806
go.sia.tech/gofakes3 v0.0.5
go.sia.tech/hostd v1.1.3-0.20241212081824-0f6d95b852db
go.sia.tech/hostd v1.1.3-0.20241212215223-9e3440475bed
go.sia.tech/jape v0.12.1
go.sia.tech/mux v1.3.0
go.sia.tech/web/renterd v0.69.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ go.sia.tech/coreutils v0.7.1-0.20241211045514-6881993d8806 h1:zmLtpmFQPKMukYMiQB
go.sia.tech/coreutils v0.7.1-0.20241211045514-6881993d8806/go.mod h1:6z3oHrQqcLoFEAT/l6XnvOivEGXgIfWBKcq0OqsouWA=
go.sia.tech/gofakes3 v0.0.5 h1:vFhVBUFbKE9ZplvLE2w4TQxFMQyF8qvgxV4TaTph+Vw=
go.sia.tech/gofakes3 v0.0.5/go.mod h1:LXEzwGw+OHysWLmagleCttX93cJZlT9rBu/icOZjQ54=
go.sia.tech/hostd v1.1.3-0.20241212081824-0f6d95b852db h1:ey3ezMYHPzY+FZ4yL8xsAWnCJWI2J9z4rtpmRa8dj0A=
go.sia.tech/hostd v1.1.3-0.20241212081824-0f6d95b852db/go.mod h1:6wTgoXKmsLQT22lUcHI4/dUcb3mhXFR+9zYWIki8Qho=
go.sia.tech/hostd v1.1.3-0.20241212215223-9e3440475bed h1:C42AxWwwoP13EhZsdWwR17Rc9S7gXI4JnRN0AyZRxc8=
go.sia.tech/hostd v1.1.3-0.20241212215223-9e3440475bed/go.mod h1:6wTgoXKmsLQT22lUcHI4/dUcb3mhXFR+9zYWIki8Qho=
go.sia.tech/jape v0.12.1 h1:xr+o9V8FO8ScRqbSaqYf9bjj1UJ2eipZuNcI1nYousU=
go.sia.tech/jape v0.12.1/go.mod h1:wU+h6Wh5olDjkPXjF0tbZ1GDgoZ6VTi4naFw91yyWC4=
go.sia.tech/mux v1.3.0 h1:hgR34IEkqvfBKUJkAzGi31OADeW2y7D6Bmy/Jcbop9c=
Expand Down
2 changes: 1 addition & 1 deletion internal/test/e2e/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,7 @@ func announceHosts(hosts []*Host) error {
for _, host := range hosts {
settings := defaultHostSettings
settings.NetAddress = host.rhp4Listener.Addr().(*net.TCPAddr).IP.String()
if err := host.settings.UpdateSettings(settings); err != nil {
if err := host.UpdateSettings(settings); err != nil {
return err
}
if err := host.settings.Announce(); err != nil {
Expand Down
48 changes: 41 additions & 7 deletions internal/test/e2e/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ import (
"go.sia.tech/renterd/internal/utils"
"go.sia.tech/renterd/object"
"go.sia.tech/renterd/stores/sql/sqlite"
"go.uber.org/zap"
"lukechampine.com/frand"
)

Expand Down Expand Up @@ -2859,6 +2858,7 @@ func TestContractFundsReturnWhenHostOffline(t *testing.T) {
})
}

// TODO: upload and download
func TestV1ToV2Transition(t *testing.T) {
// create a chain manager with a custom network that starts before the v2
// allow height
Expand All @@ -2874,18 +2874,16 @@ func TestV1ToV2Transition(t *testing.T) {
// custom autopilot config
apCfg := test.AutopilotConfig
apCfg.Contracts.Amount = 2
apCfg.Contracts.Period = 1000 // make sure contracts are not scheduled for renew before reaching the allowheight
apCfg.Contracts.Period = 1000 // make sure we handle trying to form contracts with a proof height after the v2 require height
apCfg.Contracts.RenewWindow = 50

// create a test cluster
nHosts := 3
l, _ := zap.NewDevelopment()
cluster := newTestCluster(t, testClusterOptions{
autopilotConfig: &apCfg,
hosts: 0, // add hosts manually later
cm: cm,
uploadPacking: false, // disable to make sure we don't accidentally serve data from disk
logger: l,
})
defer cluster.Shutdown()
tt := cluster.tt
Expand All @@ -2912,6 +2910,8 @@ func TestV1ToV2Transition(t *testing.T) {
for _, c := range contracts {
if c.V2 {
t.Fatal("should not have formed v2 contracts")
} else if c.EndHeight() != network.HardforkV2.RequireHeight-1 {
t.Fatalf("expected proof height to be %v, got %v", network.HardforkV2.RequireHeight-1, c.EndHeight())
}
contractHosts[c.HostKey] = struct{}{}
}
Expand All @@ -2929,9 +2929,43 @@ func TestV1ToV2Transition(t *testing.T) {
cluster.MineBlocks(1)
time.Sleep(100 * time.Millisecond)
}
time.Sleep(time.Second)

// check the contracts again
contracts, err = cluster.Bus.Contracts(context.Background(), api.ContractsOpts{FilterMode: api.ContractFilterModeAll})
// check that we have 1 archived contract for every contract we had before
archivedContracts, err := cluster.Bus.Contracts(context.Background(), api.ContractsOpts{FilterMode: api.ContractFilterModeArchived})
tt.OK(err)
fmt.Println("contracts", len(contracts))
if len(archivedContracts) != nHosts-1 {
t.Fatalf("expected %v archived contracts, got %v", 2*(nHosts-1), len(archivedContracts))
}

// they should be on nHosts-1 unique hosts
usedHosts := make(map[types.PublicKey]struct{})
for _, c := range archivedContracts {
if c.ArchivalReason != "migrated to v2" {
t.Fatalf("expected archival reason to be 'migrated to v2', got %v", c.ArchivalReason)
} else if c.V2 {
t.Fatalf("expected contract to be v1, got v2")
}
usedHosts[c.HostKey] = struct{}{}
}
if len(usedHosts) != nHosts-1 {
t.Fatalf("expected %v unique hosts, got %v", nHosts-1, len(usedHosts))
}

// we should have the same number of active contracts
activeContracts, err := cluster.Bus.Contracts(context.Background(), api.ContractsOpts{FilterMode: api.ContractFilterModeActive})
tt.OK(err)
if len(activeContracts) != nHosts-1 {
t.Fatalf("expected %v active contracts, got %v", nHosts-1, len(activeContracts))
}

// they should be on the same hosts as before
for _, c := range activeContracts {
if _, ok := usedHosts[c.HostKey]; !ok {
t.Fatal("host not found in used hosts")
} else if !c.V2 {
t.Fatal("expected contract to be v2, got v1", c.ID, c.ArchivalReason)
}
delete(usedHosts, c.HostKey)
}
}

0 comments on commit c20ce92

Please sign in to comment.