Skip to content

Commit

Permalink
Merge dev -> master (#1355)
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisSchinnerl authored Jun 28, 2024
2 parents c140b52 + e6acd77 commit 4b3ab23
Show file tree
Hide file tree
Showing 147 changed files with 12,397 additions and 8,166 deletions.
4 changes: 4 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ updates:
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
groups:
all-dependencies:
patterns:
- "*"
2 changes: 1 addition & 1 deletion .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ on:
push:
branches: [ "dev", "master" ]
pull_request:
branches: [ "dev", "master" ]
branches: [ "master" ]
schedule:
- cron: '22 22 * * 4'

Expand Down
32 changes: 19 additions & 13 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,11 @@ on:
- master

jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ ubuntu-latest , macos-latest, windows-latest ]
go-version: [ '1.21', '1.22' ]
analyze:
runs-on: ubuntu-latest
steps:
- name: Configure Windows
if: matrix.os == 'windows-latest'
run: git config --global core.autocrlf false # fixes go lint fmt error
- name: Checkout
uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go-version }}
- name: Lint
uses: golangci/golangci-lint-action@v3
with:
Expand All @@ -36,6 +25,23 @@ jobs:
autopilot
bus bus/client
worker worker/client
test:
needs: analyze
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ ubuntu-latest , macos-latest, windows-latest ]
go-version: [ '1.21', '1.22' ]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go-version }}
- name: Configure Windows
if: matrix.os == 'windows-latest'
run: git config --global core.autocrlf false # fixes go lint fmt error
- name: Configure MySQL
if: matrix.os == 'ubuntu-latest'
uses: mirromutth/[email protected]
Expand Down
316 changes: 246 additions & 70 deletions README.md

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions api/bus.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
package api

import (
"errors"

"go.sia.tech/core/types"
)

var (
ErrMarkerNotFound = errors.New("marker not found")
ErrMaxFundAmountExceeded = errors.New("renewal exceeds max fund amount")
)

type (
// ConsensusState holds the current blockheight and whether we are synced or not.
ConsensusState struct {
Expand Down
175 changes: 175 additions & 0 deletions api/events.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
package api

import (
"encoding/json"
"errors"
"fmt"
"time"

"go.sia.tech/core/types"
"go.sia.tech/renterd/webhooks"
)

const (
ModuleConsensus = "consensus"
ModuleContract = "contract"
ModuleContractSet = "contract_set"
ModuleSetting = "setting"

EventUpdate = "update"
EventDelete = "delete"
EventArchive = "archive"
EventRenew = "renew"
)

var (
ErrUnknownEvent = errors.New("unknown event")
)

type (
EventConsensusUpdate struct {
ConsensusState
TransactionFee types.Currency `json:"transactionFee"`
Timestamp time.Time `json:"timestamp"`
}

EventContractArchive struct {
ContractID types.FileContractID `json:"contractID"`
Reason string `json:"reason"`
Timestamp time.Time `json:"timestamp"`
}

EventContractRenew struct {
Renewal ContractMetadata `json:"renewal"`
Timestamp time.Time `json:"timestamp"`
}

EventContractSetUpdate struct {
Name string `json:"name"`
ContractIDs []types.FileContractID `json:"contractIDs"`
Timestamp time.Time `json:"timestamp"`
}

EventSettingUpdate struct {
Key string `json:"key"`
Update interface{} `json:"update"`
Timestamp time.Time `json:"timestamp"`
}

EventSettingDelete struct {
Key string `json:"key"`
Timestamp time.Time `json:"timestamp"`
}
)

var (
WebhookConsensusUpdate = func(url string, headers map[string]string) webhooks.Webhook {
return webhooks.Webhook{
Event: EventUpdate,
Headers: headers,
Module: ModuleConsensus,
URL: url,
}
}

WebhookContractArchive = func(url string, headers map[string]string) webhooks.Webhook {
return webhooks.Webhook{
Event: EventArchive,
Headers: headers,
Module: ModuleContract,
URL: url,
}
}

WebhookContractRenew = func(url string, headers map[string]string) webhooks.Webhook {
return webhooks.Webhook{
Event: EventRenew,
Headers: headers,
Module: ModuleContract,
URL: url,
}
}

WebhookContractSetUpdate = func(url string, headers map[string]string) webhooks.Webhook {
return webhooks.Webhook{
Event: EventUpdate,
Headers: headers,
Module: ModuleContractSet,
URL: url,
}
}

WebhookSettingUpdate = func(url string, headers map[string]string) webhooks.Webhook {
return webhooks.Webhook{
Event: EventUpdate,
Headers: headers,
Module: ModuleSetting,
URL: url,
}
}

WebhookSettingDelete = func(url string, headers map[string]string) webhooks.Webhook {
return webhooks.Webhook{
Event: EventDelete,
Headers: headers,
Module: ModuleSetting,
URL: url,
}
}
)

func ParseEventWebhook(event webhooks.Event) (interface{}, error) {
bytes, err := json.Marshal(event.Payload)
if err != nil {
return nil, err
}
switch event.Module {
case ModuleContract:
switch event.Event {
case EventArchive:
var e EventContractArchive
if err := json.Unmarshal(bytes, &e); err != nil {
return nil, err
}
return e, nil
case EventRenew:
var e EventContractRenew
if err := json.Unmarshal(bytes, &e); err != nil {
return nil, err
}
return e, nil
}
case ModuleContractSet:
if event.Event == EventUpdate {
var e EventContractSetUpdate
if err := json.Unmarshal(bytes, &e); err != nil {
return nil, err
}
return e, nil
}
case ModuleConsensus:
if event.Event == EventUpdate {
var e EventConsensusUpdate
if err := json.Unmarshal(bytes, &e); err != nil {
return nil, err
}
return e, nil
}
case ModuleSetting:
switch event.Event {
case EventUpdate:
var e EventSettingUpdate
if err := json.Unmarshal(bytes, &e); err != nil {
return nil, err
}
return e, nil
case EventDelete:
var e EventSettingDelete
if err := json.Unmarshal(bytes, &e); err != nil {
return nil, err
}
return e, nil
}
}
return nil, fmt.Errorf("%w: module %s event %s", ErrUnknownEvent, event.Module, event.Event)
}
6 changes: 4 additions & 2 deletions api/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ type (
Blocked bool `json:"blocked"`
Checks map[string]HostCheck `json:"checks"`
StoredData uint64 `json:"storedData"`
Subnets []string `json:"subnets"`
}

HostAddress struct {
Expand All @@ -181,10 +182,11 @@ type (

HostScan struct {
HostKey types.PublicKey `json:"hostKey"`
PriceTable rhpv3.HostPriceTable
Settings rhpv2.HostSettings
Subnets []string
Success bool
Timestamp time.Time
Settings rhpv2.HostSettings
PriceTable rhpv3.HostPriceTable
}

HostPriceTable struct {
Expand Down
8 changes: 5 additions & 3 deletions api/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,9 +228,11 @@ type (
}

ListObjectOptions struct {
Prefix string
Marker string
Limit int
Prefix string
Marker string
Limit int
SortBy string
SortDir string
}

SearchObjectOptions struct {
Expand Down
72 changes: 72 additions & 0 deletions api/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
const (
SettingContractSet = "contractset"
SettingGouging = "gouging"
SettingPricePinning = "pricepinning"
SettingRedundancy = "redundancy"
SettingS3Authentication = "s3authentication"
SettingUploadPacking = "uploadpacking"
Expand Down Expand Up @@ -80,6 +81,55 @@ type (
MigrationSurchargeMultiplier uint64 `json:"migrationSurchargeMultiplier"`
}

// PricePinSettings holds the configuration for pinning certain settings to
// a specific currency (e.g., USD). It uses a Forex API to fetch the current
// exchange rate, allowing users to set prices in USD instead of SC.
PricePinSettings struct {
// Enabled can be used to either enable or temporarily disable price
// pinning. If enabled, both the currency and the Forex endpoint URL
// must be valid.
Enabled bool `json:"enabled"`

// Currency is the external three-letter currency code.
Currency string `json:"currency"`

// ForexEndpointURL is the endpoint that returns the exchange rate for
// Siacoin against the underlying currency.
ForexEndpointURL string `json:"forexEndpointURL"`

// Threshold is a percentage between 0 and 1 that determines when the
// pinned settings are updated based on the exchange rate at the time.
Threshold float64 `json:"threshold"`

// Autopilots contains the pinned settings for every autopilot.
Autopilots map[string]AutopilotPins `json:"autopilots,omitempty"`

// GougingSettingsPins contains the pinned settings for the gouging
// settings.
GougingSettingsPins GougingSettingsPins `json:"gougingSettingsPins,omitempty"`
}

// AutopilotPins contains the available autopilot settings that can be
// pinned.
AutopilotPins struct {
Allowance Pin `json:"allowance"`
}

// GougingSettingsPins contains the available gouging settings that can be
// pinned.
GougingSettingsPins struct {
MaxDownload Pin `json:"maxDownload"`
MaxRPCPrice Pin `json:"maxRPCPrice"`
MaxStorage Pin `json:"maxStorage"`
MaxUpload Pin `json:"maxUpload"`
}

// A Pin is a pinned price in an external currency.
Pin struct {
Pinned bool `json:"pinned"`
Value float64 `json:"value"`
}

// RedundancySettings contain settings that dictate an object's redundancy.
RedundancySettings struct {
MinShards int `json:"minShards"`
Expand All @@ -98,6 +148,28 @@ type (
}
)

// IsPinned returns true if the pin is enabled and the value is greater than 0.
func (p Pin) IsPinned() bool {
return p.Pinned && p.Value > 0
}

// Validate returns an error if the price pin settings are not considered valid.
func (pps PricePinSettings) Validate() error {
if !pps.Enabled {
return nil
}
if pps.ForexEndpointURL == "" {
return fmt.Errorf("price pin settings must have a forex endpoint URL")
}
if pps.Currency == "" {
return fmt.Errorf("price pin settings must have a currency")
}
if pps.Threshold <= 0 || pps.Threshold >= 1 {
return fmt.Errorf("price pin settings must have a threshold between 0 and 1")
}
return nil
}

// Validate returns an error if the gouging settings are not considered valid.
func (gs GougingSettings) Validate() error {
if gs.HostBlockHeightLeeway < 3 {
Expand Down
Loading

0 comments on commit 4b3ab23

Please sign in to comment.