Skip to content
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
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.24-bookworm AS build
FROM golang:1.25-alpine AS build

WORKDIR /etracker

Expand All @@ -10,7 +10,7 @@ ARG VERSION
ARG DATE

RUN CGO_ENABLED=0 GOOS=linux GOARCH=arm64 \
go build -ldflags="-w -s -X github.com/storacha/etracker/internal/build.version=$VERSION -X github.com/storacha/etracker/internal/build.Date=$DATE -X github.com/storacha/etracker/internal/build.BuiltBy=docker" \
go build -ldflags="-w -s -X github.com/storacha/etracker/internal/build.version=$VERSION -X github.com/storacha/etracker/internal/build.Date=$DATE -X github.com/storacha/etracker/internal/build.BuiltBy=docker" \
-o etracker github.com/storacha/etracker/cmd/etracker

FROM scratch
Expand Down
33 changes: 32 additions & 1 deletion cmd/etracker/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ import (
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
"github.com/spf13/cobra"
"github.com/spf13/viper"
ucancap "github.com/storacha/go-libstoracha/capabilities/ucan"
"github.com/storacha/go-ucanto/core/delegation"
"github.com/storacha/go-ucanto/did"
ed25519 "github.com/storacha/go-ucanto/principal/ed25519/signer"
"github.com/storacha/go-ucanto/principal/signer"
"github.com/storacha/go-ucanto/ucan"

"github.com/storacha/etracker/internal/config"
"github.com/storacha/etracker/internal/consolidator"
Expand Down Expand Up @@ -213,6 +216,33 @@ func startService(cmd *cobra.Command, args []string) error {
return fmt.Errorf("creating principal resolver: %w", err)
}

// Trust attestations from trusted authorities
var authProofs []delegation.Delegation
for _, authority := range cfg.TrustedAuthorities {
auth, err := did.Parse(authority)
if err != nil {
return fmt.Errorf("parsing trusted authority: %w", err)
}

attestDlg, err := delegation.Delegate(
id,
auth,
[]ucan.Capability[ucan.NoCaveats]{
ucan.NewCapability(
ucancap.AttestAbility,
id.DID().String(),
ucan.NoCaveats{},
),
},
delegation.WithNoExpiration(),
)
if err != nil {
return err
}

authProofs = append(authProofs, attestDlg)
}

// Create and start consolidator
interval := time.Duration(cfg.ConsolidationInterval) * time.Second
batchSize := cfg.ConsolidationBatchSize
Expand All @@ -228,7 +258,7 @@ func startService(cmd *cobra.Command, args []string) error {
interval,
batchSize,
presolver.ResolveDIDKey,
cfg.TrustedAuthorities,
authProofs,
)
if err != nil {
return fmt.Errorf("creating consolidator: %w", err)
Expand All @@ -246,6 +276,7 @@ func startService(cmd *cobra.Command, args []string) error {
server.WithAdminCreds(cfg.AdminDashboardUser, cfg.AdminDashboardPassword),
server.WithPricing(cfg.ClientEgressUSDPerTiB, cfg.ProviderEgressUSDPerTiB),
server.WithPrincipalResolver(presolver),
server.WithAuthorityProofs(authProofs...),
)
if err != nil {
return fmt.Errorf("creating server: %w", err)
Expand Down
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/storacha/etracker

go 1.24.4
go 1.25.3

require (
github.com/aws/aws-sdk-go-v2 v1.39.2
Expand All @@ -14,7 +14,7 @@ require (
github.com/prometheus/client_golang v1.23.2
github.com/spf13/cobra v1.2.1
github.com/spf13/viper v1.8.1
github.com/storacha/go-libstoracha v0.4.0
github.com/storacha/go-libstoracha v0.7.1
github.com/storacha/go-ucanto v0.7.1
github.com/stretchr/testify v1.11.1
go.opentelemetry.io/otel v1.38.0
Expand Down Expand Up @@ -126,12 +126,12 @@ require (
golang.org/x/crypto v0.41.0 // indirect
golang.org/x/exp v0.0.0-20250606033433-dcc06ee1d476 // indirect
golang.org/x/net v0.43.0 // indirect
golang.org/x/sys v0.35.0 // indirect
golang.org/x/sys v0.36.0 // indirect
golang.org/x/text v0.28.0 // indirect
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect
google.golang.org/protobuf v1.36.8 // indirect
gopkg.in/ini.v1 v1.62.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
lukechampine.com/blake3 v1.4.0 // indirect
lukechampine.com/blake3 v1.4.1 // indirect
)
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -517,8 +517,8 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.8.1 h1:Kq1fyeebqsBfbjZj4EL7gj2IO0mMaiyjYUWcUsl2O44=
github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
github.com/storacha/go-libstoracha v0.4.0 h1:QkJKOE4zQ13p478tMr6C5pY3VHQxqaBE8kGDiY3TqTQ=
github.com/storacha/go-libstoracha v0.4.0/go.mod h1:PLTFCREzKlZMY9cuZDCJUh2DiCWLKQEyTQhYM1muy9M=
github.com/storacha/go-libstoracha v0.7.1 h1:qsSIAuxfKFDehgl0Yt1UyOUMaIGN1QnMKKsO3BXoBvw=
github.com/storacha/go-libstoracha v0.7.1/go.mod h1:htUh/VZ0qHRLPJKWZsgXv9mCOqlAFGTVS//ApvQVNf0=
github.com/storacha/go-ucanto v0.7.1 h1:/KRsCltQt57+3sqNqM8ygh9TwA6+0DGC2LIYaOnhcSY=
github.com/storacha/go-ucanto v0.7.1/go.mod h1:O35Ze4x18EWtz3ftRXXd/mTZ+b8OQVjYYrnadJ/xNjg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
Expand Down Expand Up @@ -763,8 +763,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
Expand Down Expand Up @@ -976,8 +976,8 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
lukechampine.com/blake3 v1.4.0 h1:xDbKOZCVbnZsfzM6mHSYcGRHZ3YrLDzqz8XnV4uaD5w=
lukechampine.com/blake3 v1.4.0/go.mod h1:MQJNQCTnR+kwOP/JEZSxj3MaQjp80FOFSNMMHXcSeX0=
lukechampine.com/blake3 v1.4.1 h1:I3Smz7gso8w4/TunLKec6K2fn+kyKtDxr/xcQEN84Wg=
lukechampine.com/blake3 v1.4.1/go.mod h1:QFosUxmjB8mnrWFSNwKmvxHpfY72bmD2tQ0kBMM3kwo=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
30 changes: 1 addition & 29 deletions internal/consolidator/consolidator.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (
logging "github.com/ipfs/go-log/v2"
"github.com/storacha/go-libstoracha/capabilities/space/content"
capegress "github.com/storacha/go-libstoracha/capabilities/space/egress"
ucancap "github.com/storacha/go-libstoracha/capabilities/ucan"
"github.com/storacha/go-ucanto/client"
"github.com/storacha/go-ucanto/core/car"
"github.com/storacha/go-ucanto/core/dag/blockstore"
Expand Down Expand Up @@ -71,35 +70,8 @@ func New(
interval time.Duration,
batchSize int,
presolver validator.PrincipalResolverFunc,
trustedAuthorities []string,
authProofs []delegation.Delegation,
) (*Consolidator, error) {
// trust attestations from trusted authorities
var authProofs []delegation.Delegation
for _, authority := range trustedAuthorities {
auth, err := did.Parse(authority)
if err != nil {
return nil, fmt.Errorf("parsing trusted authority: %w", err)
}

attestDlg, err := delegation.Delegate(
id,
auth,
[]ucan.Capability[ucan.NoCaveats]{
ucan.NewCapability(
ucancap.AttestAbility,
id.DID().String(),
ucan.NoCaveats{},
),
},
delegation.WithNoExpiration(),
)
if err != nil {
return nil, err
}

authProofs = append(authProofs, attestDlg)
}

retrieveValidationCtx := validator.NewValidationContext(
id.Verifier(),
content.Retrieve,
Expand Down
15 changes: 14 additions & 1 deletion internal/consolidator/consolidator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,19 @@ func TestValidateRetrievalReceipt(t *testing.T) {

// trust attestations from the upload service
uploadServiceID := testutil.WebService
attestDlg, err := delegation.Delegate(
consolidatorID,
uploadServiceID,
[]ucan.Capability[ucan.NoCaveats]{
ucan.NewCapability(
ucancap.AttestAbility,
consolidatorID.DID().String(),
ucan.NoCaveats{},
),
},
delegation.WithNoExpiration(),
)
require.NoError(t, err)

knownProvider, err := did.Parse("did:web:up.test.storacha.network")
require.NoError(t, err)
Expand All @@ -85,7 +98,7 @@ func TestValidateRetrievalReceipt(t *testing.T) {

return did.Undef, validator.NewDIDKeyResolutionError(input, fmt.Errorf("%s not found in mapping", input.String()))
},
[]string{uploadServiceID.DID().String()},
[]delegation.Delegation{attestDlg},
)
require.NoError(t, err)

Expand Down
1 change: 1 addition & 0 deletions internal/db/customer/customer.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ type ListResult struct {

type CustomerTable interface {
List(ctx context.Context, limit int, cursor *string) (*ListResult, error)
Has(ctx context.Context, customerDID did.DID) (bool, error)
}
17 changes: 17 additions & 0 deletions internal/db/customer/dynamodb.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,20 @@ func decodeToken(token string) (map[string]types.AttributeValue, error) {

return key, nil
}

func (d *DynamoCustomerTable) Has(ctx context.Context, customerDID did.DID) (bool, error) {
input := &dynamodb.GetItemInput{
TableName: aws.String(d.tableName),
Key: map[string]types.AttributeValue{
"customer": &types.AttributeValueMemberS{Value: customerDID.String()},
},
ProjectionExpression: aws.String("customer"),
}

result, err := d.client.GetItem(ctx, input)
if err != nil {
return false, fmt.Errorf("checking customer existence: %w", err)
}

return result.Item != nil, nil
}
12 changes: 7 additions & 5 deletions internal/db/spacestats/dynamodb.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,25 +47,27 @@ func (d *DynamoSpaceStatsTable) Record(ctx context.Context, space did.DID, egres
return nil
}

func (d *DynamoSpaceStatsTable) GetDailyStats(ctx context.Context, space did.DID, since time.Time) ([]DailyStats, error) {
func (d *DynamoSpaceStatsTable) GetDailyStats(ctx context.Context, space did.DID, from time.Time, to time.Time) ([]DailyStats, error) {
stats := make([]DailyStats, 0)
var exclusiveStartKey map[string]types.AttributeValue

// Format since date to YYYY-MM-DD for comparison
sinceDate := since.UTC().Format("2006-01-02")
// Format dates to YYYY-MM-DD for comparison
fromDate := from.UTC().Format("2006-01-02")
toDate := to.UTC().Format("2006-01-02")

// Keep querying until we get all results (handle pagination)
for {
input := &dynamodb.QueryInput{
TableName: aws.String(d.tableName),
KeyConditionExpression: aws.String("#space = :space AND #date >= :since"),
KeyConditionExpression: aws.String("#space = :space AND #date BETWEEN :from AND :to"),
ExpressionAttributeNames: map[string]string{
"#space": "space",
"#date": "date",
},
ExpressionAttributeValues: map[string]types.AttributeValue{
":space": &types.AttributeValueMemberS{Value: space.String()},
":since": &types.AttributeValueMemberS{Value: sinceDate},
":from": &types.AttributeValueMemberS{Value: fromDate},
":to": &types.AttributeValueMemberS{Value: toDate},
},
ProjectionExpression: aws.String("#date, egress"),
}
Expand Down
2 changes: 1 addition & 1 deletion internal/db/spacestats/spacestats.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ type DailyStats struct {

type SpaceStatsTable interface {
Record(ctx context.Context, space did.DID, egress uint64) error
GetDailyStats(ctx context.Context, space did.DID, since time.Time) ([]DailyStats, error)
GetDailyStats(ctx context.Context, space did.DID, from time.Time, to time.Time) ([]DailyStats, error)
}
Loading