costs

package
v0.4.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 24, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package costs provides cost calculation for storage operations.

It computes upload costs from the warmstorage PriceList, data set sizes, one-time operation fees, lockup requirements, and CDN options. The calculation matches on-chain Solidity integer division for accuracy.

Entry points

Payment account summary moved to `payments.Service.AccountSummary`. The older Service.GetAccountSummary method remains for compatibility.

Glossary

Epoch — Filecoin block interval (30 seconds on mainnet and calibration). All on-chain rates and durations are denominated in epochs; 120 epochs equal one hour, ~86 400 equal one month. On-chain lockup rates are per-epoch; effective monthly rates preserve monthly pricing precision for display and comparison.

Basis points (bps) — one hundredth of one percent (1 bps = 0.01 %). Commission rates returned by warmstorage are expressed in basis points out of 10 000 (e.g. 500 bps = 5 %).

Fees — one-time operation charges such as dataset creation and add-pieces submission fees. Add-pieces fees are counted per PDP batch.

Lifecycle reserve — the flat lockup required when creating a dataset. It is separate from one-time operation fees.

Lockup — funds reserved on the FilecoinPay contract to guarantee a stream of payments. `LockupRatePerEpoch` is the per-epoch drain rate; `FundedUntilEpoch` is the epoch at which existing funds are exhausted at that rate.

Stability

0.x phase: public API may change between minor releases.

Example

Example demonstrates fetching an account summary via costs.Service. In practice a Service is obtained from synapse.Client.Costs.

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/ethereum/go-ethereum/common"
	"github.com/strahe/synapse-go/costs"
)

func main() {
	var svc *costs.Service // obtained from synapse.Client.Costs()

	ctx := context.Background()
	owner := common.HexToAddress("0x...")

	summary, err := svc.GetAccountSummary(ctx, owner) //nolint:staticcheck // compatibility example for legacy costs callers
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(summary.AvailableFunds)
}

Index

Examples

Constants

View Source
const (
	// DefaultExtraRunwayEpochs adds no runway above the lockup period.
	DefaultExtraRunwayEpochs int64 = 0
	// DefaultBufferEpochs is a 5-epoch deposit cushion for transaction execution latency.
	DefaultBufferEpochs int64 = 5
	// DefaultLockupPeriod is the standard lockup horizon (30 days in epochs).
	DefaultLockupPeriod int64 = chain.EpochsPerMonth
)

Variables

View Source
var ErrClosed = lifecycle.ErrClosed

ErrClosed is returned when a method is called after the owning Client has been closed. It aliases the shared closed-client sentinel.

View Source
var ErrUninitialized = errors.New("costs: service not initialized; use costs.New")

ErrUninitialized is returned when a method is invoked on a zero-value Service (one that was not constructed via New).

Functions

func CDNFixedLockupValue deprecated

func CDNFixedLockupValue() *big.Int

CDNFixedLockupValue returns the legacy fixed lockup amount for new CDN-enabled datasets (1.0 USDFC).

Deprecated: Use warmstorage.PriceList.Lockups.CDNLockupAmount. The caller owns the returned value and may modify it freely.

func CalculateDepositNeeded

func CalculateDepositNeeded(calc DepositCalculation) *big.Int

CalculateDepositNeeded computes the USDFC deposit required to cover lockup, runway, and buffer.

Buffer is skipped when currentLockupRate is zero and isNewDataSet is true: the deposit lands before the payment rail is created so the contract cannot yet drain it.

Nil *big.Int fields are treated as zero. Negative epoch counts are clamped to zero.

Types

type AccountSummary

type AccountSummary struct {
	Funds                 *big.Int
	AvailableFunds        *big.Int
	Debt                  *big.Int
	LockupRatePerEpoch    *big.Int
	LockupRatePerMonth    *big.Int
	FundedUntilEpoch      *big.Int
	RunwayInEpochs        *big.Int
	GrossCoverageInEpochs *big.Int
	CurrentEpoch          *big.Int
}

AccountSummary is the snapshot of an account's payment state.

type AdditionalLockup

type AdditionalLockup struct {
	RateDeltaPerEpoch *big.Int
	StreamingLockup   *big.Int
	LifecycleLockup   *big.Int
	CDNLockup         *big.Int
	CacheMissLockup   *big.Int
	Total             *big.Int

	// Deprecated: Use RateDeltaPerEpoch.
	RateDelta *big.Int
	// Deprecated: Use StreamingLockup.
	RateLockup *big.Int
	// Deprecated: Use CDNLockup and CacheMissLockup.
	CDNFixedLockup *big.Int
	// Deprecated: Use LifecycleLockup.
	SybilFee *big.Int
	// Deprecated: Use Total.
	TotalLockup *big.Int
}

AdditionalLockup is the incremental lockup required when adding data to a dataset.

func CalculateAdditionalLockupRequired

func CalculateAdditionalLockupRequired(
	dataSizeBytes *big.Int,
	currentDataSetSizeBytes *big.Int,
	priceList *warmstorage.PriceList,
	lockupPeriod *big.Int,
	isNewDataSet bool,
	enableCDN bool,
) AdditionalLockup

CalculateAdditionalLockupRequired returns the incremental lockup needed to store uploadSizeBytes into a dataset that currently holds currentDataSetSizeBytes. Nil dataSizeBytes, currentDataSetSizeBytes, and priceList use zero-value defaults.

type ContractCaller

type ContractCaller interface {
	CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error)
	BlockNumber(ctx context.Context) (uint64, error)
}

ContractCaller is the chain reader accepted by Service. CallContract remains part of the public interface for compatibility; current cost calculations only use BlockNumber.

type DepositCalculation added in v0.3.1

type DepositCalculation struct {
	// AdditionalLockup is the incremental lockup required by the upload.
	AdditionalLockup *big.Int
	// Fees are one-time operation fees required by the upload.
	Fees *big.Int
	// RateDelta is the incremental per-epoch payment rate added by the upload.
	RateDelta *big.Int
	// CurrentLockupRate is the account's existing per-epoch payment rate.
	CurrentLockupRate *big.Int
	// Debt is already-accrued payment debt that must be covered.
	Debt *big.Int
	// AvailableFunds is the account balance available after projected lockup.
	AvailableFunds *big.Int
	// RunwayInEpochs is the current account runway after projection.
	RunwayInEpochs *big.Int
	// ExtraRunwayEpochs is extra epoch runway on top of the required lockup.
	ExtraRunwayEpochs int64
	// BufferEpochs is the deposit buffer for execution latency.
	// Zero means no buffer for direct calculations; service options apply their
	// own default before calling CalculateDepositNeeded.
	BufferEpochs int64
	// IsNewDataSet is true when creating a fresh dataset.
	IsNewDataSet bool
}

DepositCalculation is the input to CalculateDepositNeeded.

type EffectiveRate

type EffectiveRate struct {
	RatePerEpoch *big.Int
	RatePerMonth *big.Int
}

EffectiveRate is the per-epoch and per-month storage rate for a given data size. RatePerEpoch uses integer division to match on-chain Solidity truncation. RatePerMonth preserves monthly pricing precision for display and comparison.

func CalculateEffectiveRate

func CalculateEffectiveRate(
	sizeBytes *big.Int,
	pricePerTiBPerMonth *big.Int,
	datasetFeePerMonth *big.Int,
	epochsPerMonth int64,
) EffectiveRate

CalculateEffectiveRate computes the storage rate for the given total data size. Integer division is used to match on-chain Solidity truncation. If epochsPerMonth is zero or negative, chain.EpochsPerMonth is used as a safe default. Nil sizeBytes, pricePerTiBPerMonth, or datasetFeePerMonth are treated as zero.

type MultiContextCosts

type MultiContextCosts struct {
	// RatePerEpoch is the sum of per-context effective rates (post-upload).
	RatePerEpoch *big.Int
	// RatePerMonth is the sum of per-context monthly effective rates.
	RatePerMonth *big.Int
	// Fees is the aggregate one-time fee breakdown.
	Fees UploadFees
	// Lockup is the aggregate lockup breakdown.
	Lockup AdditionalLockup
	// DepositNeeded is the single USDFC deposit covering all contexts.
	DepositNeeded *big.Int
	// RequiredLockupPeriod is the max lockup period required for FWSS
	// approval, sourced from the price list.
	RequiredLockupPeriod *big.Int
	// NeedsFWSSMaxApproval is true when the FWSS operator does not yet
	// hold max approval for the payer.
	NeedsFWSSMaxApproval bool
	// Ready is true when DepositNeeded is zero and FWSS approval is set.
	Ready bool
}

MultiContextCosts is the aggregate cost view across multiple upload targets: a single DepositNeeded / NeedsFWSSMaxApproval / Ready, plus summed RatePerEpoch / RatePerMonth covering all refs.

type MultiContextRef

type MultiContextRef struct {
	// IsNewDataSet is true when the target will create a new data set
	// on this provider (contributes lifecycle and optional CDN/cache-miss
	// lockup). When false, CurrentDataSetSizeBytes is consulted so the
	// marginal rate is computed above the existing size.
	IsNewDataSet bool

	// CurrentDataSetSizeBytes is the current on-chain size of the
	// existing data set (zero or nil when IsNewDataSet is true). When
	// unknown, pass nil and the marginal rate is computed from zero size.
	CurrentDataSetSizeBytes *big.Int

	// WithCDN toggles CDN and cache-miss lockup for this target. Only
	// meaningful when IsNewDataSet is true.
	WithCDN bool
}

MultiContextRef describes one upload target for Service.CalculateMultiContextCosts. Each ref yields its own lockup contribution; account-level debt, runway and buffer are computed once across the aggregate.

type Options

type Options struct {
	// Chain selects the network whose contract addresses are used.
	// Zero value is chain.Mainnet. Explicit addresses below override the
	// chain registry for callers that resolve current contracts dynamically.
	Chain chain.Chain

	// USDFCTokenAddress is the payment token used for account and approval
	// reads. Zero falls back to Chain.Addresses().USDFC.
	USDFCTokenAddress common.Address

	// WarmStorageAddress is the FWSS operator used for approval reads. Zero
	// falls back to Chain.Addresses().FWSS.
	WarmStorageAddress common.Address

	// WarmStorage reads on-chain service pricing. Required.
	WarmStorage WarmStorageReader

	// Payments reads account and allowance state. Required.
	Payments PaymentsReader

	// Caller provides chain reads for cost calculations. Required.
	Caller ContractCaller

	// Logger is the structured logger. If nil, logging is silent.
	Logger *slog.Logger

	// Lifecycle, when non-nil, ties this Service to the owning Client's
	// close state. After the Lifecycle is closed, every method returns
	// ErrClosed. Nil is allowed for standalone use.
	Lifecycle *lifecycle.Lifecycle
}

Options configures a Service.

type PaymentsReader

type PaymentsReader interface {
	AccountInfo(ctx context.Context, token, owner common.Address) (*payments.AccountState, error)
	ServiceApproval(ctx context.Context, token, client, operator common.Address) (*payments.OperatorApproval, error)
}

PaymentsReader is the subset of payments.Service used by costs.

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service computes upload costs and account summaries for the FWSS ecosystem. All methods are safe for concurrent use.

func New

func New(opts Options) (*Service, error)

New constructs a Service. WarmStorage, Payments and Caller must be non-nil.

func (*Service) CalculateMultiContextCosts

func (s *Service) CalculateMultiContextCosts(
	ctx context.Context,
	payer common.Address,
	dataSizeBytes *big.Int,
	refs []MultiContextRef,
	opts *UploadCostOptions,
) (*MultiContextCosts, error)

CalculateMultiContextCosts aggregates upload costs across multiple prospective contexts for a single uploaded payload of dataSizeBytes.

Each ref contributes its own lockup; debt, runway and buffer are computed once from the payer's account state.

Default buffer/runway follow DefaultBufferEpochs / DefaultExtraRunwayEpochs when the corresponding opts field is zero.

func (*Service) GetAccountSummary deprecated

func (s *Service) GetAccountSummary(ctx context.Context, owner common.Address) (*AccountSummary, error)

GetAccountSummary returns a payment health snapshot for the given owner.

Deprecated: Use payments.Service.AccountSummary for payment account state. This method is kept for compatibility.

func (*Service) GetPriceList added in v0.4.0

func (s *Service) GetPriceList(ctx context.Context) (*warmstorage.PriceList, error)

GetPriceList delegates to the warmstorage service.

func (*Service) GetServicePrice deprecated

func (s *Service) GetServicePrice(ctx context.Context) (*warmstorage.ServicePrice, error)

GetServicePrice delegates to the warmstorage service.

Deprecated: Use GetPriceList.

func (*Service) GetUploadCosts

func (s *Service) GetUploadCosts(
	ctx context.Context,
	payer common.Address,
	dataSizeBytes *big.Int,
	opts *UploadCostOptions,
) (*UploadCosts, error)

GetUploadCosts returns cost and deposit information for an upload.

payer is the client address. dataSizeBytes is the size of the new data. opts may be nil (defaults apply). opts.CurrentDataSetSizeBytes defaults to zero.

type UploadCostOptions

type UploadCostOptions struct {
	// ExtraRunwayEpochs is extra epoch runway on top of lockup. Defaults to DefaultExtraRunwayEpochs (0).
	ExtraRunwayEpochs int64
	// BufferEpochs is the deposit buffer for execution latency.
	// Zero (the zero value) uses DefaultBufferEpochs (5); there is no way to
	// request a zero-epoch buffer via this field.
	BufferEpochs int64
	// EnableCDN adds CDN and cache-miss lockup for a new dataset.
	EnableCDN bool
	// IsNewDataSet must be true when creating a fresh dataset.
	IsNewDataSet bool
	// CurrentDataSetSizeBytes is the existing payload in the dataset (0 for new datasets).
	CurrentDataSetSizeBytes *big.Int
	// PieceCount is the number of pieces added by this upload. Zero defaults
	// to one piece.
	PieceCount *big.Int
}

UploadCostOptions customises the GetUploadCosts calculation.

type UploadCosts

type UploadCosts struct {
	Rate                 EffectiveRate
	Fees                 UploadFees
	Lockup               AdditionalLockup
	DepositNeeded        *big.Int
	RequiredLockupPeriod *big.Int
	NeedsFWSSMaxApproval bool
	Ready                bool
}

UploadCosts is the result of GetUploadCosts.

type UploadFees added in v0.4.0

type UploadFees struct {
	CreateDataSetFee *big.Int
	AddPiecesFee     *big.Int
	Total            *big.Int
}

UploadFees is the one-time fee breakdown for an upload.

func CalculateUploadFees added in v0.4.0

func CalculateUploadFees(priceList *warmstorage.PriceList, isNewDataSet bool, pieceCount *big.Int) UploadFees

CalculateUploadFees computes one-time upload fees from the price list.

type WarmStorageReader

type WarmStorageReader interface {
	GetPriceList(ctx context.Context) (*warmstorage.PriceList, error)
}

WarmStorageReader is the subset of warmstorage.Service used by costs.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL