Skip to content

Commit

Permalink
Merge pull request #944 from SiaFoundation/chris/double-scan
Browse files Browse the repository at this point in the history
Scan twice before recording a failed scan
  • Loading branch information
ChrisSchinnerl authored Feb 12, 2024
2 parents 16c85e1 + 4d5a18a commit 3ab9e53
Showing 1 changed file with 67 additions and 39 deletions.
106 changes: 67 additions & 39 deletions worker/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -1369,49 +1369,44 @@ func (w *worker) Shutdown(ctx context.Context) error {
return nil
}

func (w *worker) scanHost(ctx context.Context, hostKey types.PublicKey, hostIP string) (settings rhpv2.HostSettings, pt rhpv3.HostPriceTable, elapsed time.Duration, err error) {
// record host scan
defer func() {
HostInteractionRecorderFromContext(ctx).RecordHostScan(hostdb.HostScan{
HostKey: hostKey,
Success: isSuccessfulInteraction(err),
Timestamp: time.Now(),
Settings: settings,
PriceTable: pt,
})
}()

// resolve hostIP. We don't want to scan hosts on private networks.
if !w.allowPrivateIPs {
host, _, err := net.SplitHostPort(hostIP)
if err != nil {
return rhpv2.HostSettings{}, rhpv3.HostPriceTable{}, 0, err
}
addrs, err := (&net.Resolver{}).LookupIPAddr(ctx, host)
if err != nil {
return rhpv2.HostSettings{}, rhpv3.HostPriceTable{}, 0, err
}
for _, addr := range addrs {
if isPrivateIP(addr.IP) {
return rhpv2.HostSettings{}, rhpv3.HostPriceTable{}, 0, errors.New("host is on a private network")
func (w *worker) scanHost(ctx context.Context, hostKey types.PublicKey, hostIP string) (rhpv2.HostSettings, rhpv3.HostPriceTable, time.Duration, error) {
// prepare a helper for scanning
scan := func() (rhpv2.HostSettings, rhpv3.HostPriceTable, time.Duration, error) {
// resolve hostIP. We don't want to scan hosts on private networks.
if !w.allowPrivateIPs {
host, _, err := net.SplitHostPort(hostIP)
if err != nil {
return rhpv2.HostSettings{}, rhpv3.HostPriceTable{}, 0, err
}
addrs, err := (&net.Resolver{}).LookupIPAddr(ctx, host)
if err != nil {
return rhpv2.HostSettings{}, rhpv3.HostPriceTable{}, 0, err
}
for _, addr := range addrs {
if isPrivateIP(addr.IP) {
return rhpv2.HostSettings{}, rhpv3.HostPriceTable{}, 0, errors.New("host is on a private network")
}
}
}
}

// fetch the host settings
start := time.Now()
err = w.withTransportV2(ctx, hostKey, hostIP, func(t *rhpv2.Transport) (err error) {
if settings, err = RPCSettings(ctx, t); err == nil {
// NOTE: we overwrite the NetAddress with the host address here since we
// just used it to dial the host we know it's valid
settings.NetAddress = hostIP
// fetch the host settings
start := time.Now()
var settings rhpv2.HostSettings
err := w.withTransportV2(ctx, hostKey, hostIP, func(t *rhpv2.Transport) (err error) {
if settings, err = RPCSettings(ctx, t); err == nil {
// NOTE: we overwrite the NetAddress with the host address here since we
// just used it to dial the host we know it's valid
settings.NetAddress = hostIP
}
return err
})
elapsed := time.Since(start)
if err != nil {
return settings, rhpv3.HostPriceTable{}, elapsed, err
}
return err
})
elapsed = time.Since(start)

// fetch the host pricetable
if err == nil {
// fetch the host pricetable
var pt rhpv3.HostPriceTable
err = w.transportPoolV3.withTransportV3(ctx, hostKey, settings.SiamuxAddr(), func(ctx context.Context, t *transportV3) error {
if hpt, err := RPCPriceTable(ctx, t, func(pt rhpv3.HostPriceTable) (rhpv3.PaymentMethod, error) { return nil, nil }); err != nil {
return err
Expand All @@ -1420,8 +1415,41 @@ func (w *worker) scanHost(ctx context.Context, hostKey types.PublicKey, hostIP s
return nil
}
})
return settings, pt, elapsed, err
}
return

// scan: first try
settings, pt, duration, err := scan()
if err != nil {
// scan: second try
select {
case <-ctx.Done():
case <-time.After(time.Second):
}
settings, pt, duration, err = scan()
if err == nil {
w.logger.Debug("successfully scanned host %v after retry", hostKey)
}
}

// check if the scan failed due to a shutdown - shouldn't be necessary but
// just in case since recording a failed scan might have serious
// repercussions
select {
case <-w.shutdownCtx.Done():
return rhpv2.HostSettings{}, rhpv3.HostPriceTable{}, 0, w.shutdownCtx.Err()
default:
}

// record host scan
HostInteractionRecorderFromContext(ctx).RecordHostScan(hostdb.HostScan{
HostKey: hostKey,
Success: isSuccessfulInteraction(err),
Timestamp: time.Now(),
Settings: settings,
PriceTable: pt,
})
return settings, pt, duration, err
}

func discardTxnOnErr(ctx context.Context, bus Bus, l *zap.SugaredLogger, txn types.Transaction, errContext string, err *error) {
Expand Down

0 comments on commit 3ab9e53

Please sign in to comment.