320 lines
10 KiB
Markdown
Executable File
320 lines
10 KiB
Markdown
Executable File
# Tutus Storage Interface
|
|
|
|
## Overview
|
|
|
|
The Tutus Storage Interface provides a pluggable architecture for sovereign data storage in government blockchain deployments. Different nations have different data residency requirements, and this interface allows each deployment to choose storage backends that comply with their legal framework.
|
|
|
|
## Architecture
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ Tutus Blockchain │
|
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
│ │ Block Store │ │ State Store │ │ Oracle Data │ │
|
|
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
|
|
│ │ │ │ │
|
|
│ ┌──────┴────────────────┴────────────────┴──────┐ │
|
|
│ │ Storage Interface (pkg/storage) │ │
|
|
│ └──────┬────────────────┬────────────────┬──────┘ │
|
|
└─────────┼────────────────┼────────────────┼─────────────┘
|
|
│ │ │
|
|
┌──────┴──────┐ ┌──────┴──────┐ ┌──────┴──────┐
|
|
│ NeoFS │ │ Local │ │ S3 │
|
|
│ Adapter │ │ Adapter │ │ Adapter │
|
|
└─────────────┘ └─────────────┘ └─────────────┘
|
|
│ │ │
|
|
┌──────┴──────┐ ┌──────┴──────┐ ┌──────┴──────┐
|
|
│ Private │ │ Government │ │ Sovereign │
|
|
│ NeoFS Net │ │ NAS │ │ Cloud │
|
|
└─────────────┘ └─────────────┘ └─────────────┘
|
|
```
|
|
|
|
## Data Sovereignty Compliance
|
|
|
|
### Why This Matters
|
|
|
|
Governments deploying Tutus must comply with national data residency laws:
|
|
|
|
| Jurisdiction | Law | Requirement |
|
|
|-------------|-----|-------------|
|
|
| European Union | GDPR | EU citizen data must remain in EU |
|
|
| China | Cybersecurity Law | Critical data must be stored domestically |
|
|
| Russia | Federal Law 242-FZ | Personal data of citizens stored in Russia |
|
|
| India | DPDP Act 2023 | Certain data categories require local storage |
|
|
| Brazil | LGPD | Similar to GDPR for Brazilian citizens |
|
|
|
|
### Compliance Strategy
|
|
|
|
1. **Choose Compliant Storage**: Select storage providers that operate within your jurisdiction
|
|
2. **Private Networks**: For NeoFS, deploy a private network within national borders
|
|
3. **Sovereign Clouds**: Use government-approved cloud providers
|
|
4. **Network Isolation**: Configure firewalls to prevent cross-border data transfer
|
|
5. **Encryption**: Enable encryption at rest and in transit
|
|
|
|
## Supported Providers
|
|
|
|
### NeoFS (Decentralized Storage)
|
|
|
|
Best for:
|
|
- Distributed government networks
|
|
- Multi-region deployments within a country
|
|
- High availability requirements
|
|
|
|
```yaml
|
|
storage:
|
|
provider: neofs
|
|
neofs:
|
|
endpoints:
|
|
- "grpc://neofs-node1.gov.example:8080"
|
|
- "grpc://neofs-node2.gov.example:8080"
|
|
container: "7s23kG4xLmNpQ..."
|
|
timeout: 30s
|
|
key: "/etc/tutus/neofs.key"
|
|
```
|
|
|
|
**Sovereign Deployment**: Run your own NeoFS network within national infrastructure. Do not use the public NeoFS network for government data.
|
|
|
|
### Local Filesystem
|
|
|
|
Best for:
|
|
- Single-node deployments
|
|
- Development and testing
|
|
- Air-gapped networks
|
|
- NAS/SAN-backed storage
|
|
|
|
```yaml
|
|
storage:
|
|
provider: local
|
|
local:
|
|
path: /var/lib/tutus/storage
|
|
max_size: 1099511627776 # 1TB
|
|
compression: true
|
|
```
|
|
|
|
### S3-Compatible Storage
|
|
|
|
Best for:
|
|
- Sovereign cloud providers
|
|
- Existing government cloud infrastructure
|
|
- AWS GovCloud, Azure Government, etc.
|
|
|
|
```yaml
|
|
storage:
|
|
provider: s3
|
|
s3:
|
|
endpoint: "s3.sovereign-cloud.gov.example"
|
|
region: "national-1"
|
|
bucket: "tutus-blocks"
|
|
access_key: "${S3_ACCESS_KEY}"
|
|
secret_key: "${S3_SECRET_KEY}"
|
|
use_path_style: true
|
|
```
|
|
|
|
## Interface Reference
|
|
|
|
### Provider Interface
|
|
|
|
The core interface that all storage backends must implement:
|
|
|
|
```go
|
|
type Provider interface {
|
|
// Name returns the provider identifier
|
|
Name() string
|
|
|
|
// Put stores data and returns a unique identifier
|
|
Put(ctx context.Context, data io.Reader, opts PutOptions) (ObjectID, error)
|
|
|
|
// Get retrieves data by its identifier
|
|
Get(ctx context.Context, id ObjectID) (io.ReadCloser, error)
|
|
|
|
// Delete removes an object from storage
|
|
Delete(ctx context.Context, id ObjectID) error
|
|
|
|
// Exists checks if an object exists
|
|
Exists(ctx context.Context, id ObjectID) (bool, error)
|
|
|
|
// List returns objects matching the given prefix
|
|
List(ctx context.Context, prefix string, opts ListOptions) ([]ObjectInfo, error)
|
|
|
|
// Head retrieves object metadata without content
|
|
Head(ctx context.Context, id ObjectID) (ObjectInfo, error)
|
|
|
|
// Close releases resources
|
|
Close() error
|
|
}
|
|
```
|
|
|
|
### BlockStorage Interface
|
|
|
|
Extended interface for blockchain-specific operations:
|
|
|
|
```go
|
|
type BlockStorage interface {
|
|
Provider
|
|
|
|
// PutBlock stores a block with its index
|
|
PutBlock(ctx context.Context, index uint32, data []byte) (ObjectID, error)
|
|
|
|
// GetBlock retrieves a block by its index
|
|
GetBlock(ctx context.Context, index uint32) ([]byte, error)
|
|
|
|
// GetBlockRange retrieves multiple blocks efficiently
|
|
GetBlockRange(ctx context.Context, start, end uint32) ([][]byte, error)
|
|
|
|
// GetLatestBlockIndex returns the highest block index
|
|
GetLatestBlockIndex(ctx context.Context) (uint32, error)
|
|
}
|
|
```
|
|
|
|
### StateStorage Interface
|
|
|
|
Extended interface for state snapshot operations:
|
|
|
|
```go
|
|
type StateStorage interface {
|
|
Provider
|
|
|
|
// PutState stores a state snapshot at a specific height
|
|
PutState(ctx context.Context, height uint32, data io.Reader) (ObjectID, error)
|
|
|
|
// GetState retrieves the state snapshot for a given height
|
|
GetState(ctx context.Context, height uint32) (io.ReadCloser, error)
|
|
|
|
// GetLatestState returns the most recent state snapshot
|
|
GetLatestState(ctx context.Context) (height uint32, data io.ReadCloser, err error)
|
|
}
|
|
```
|
|
|
|
## Usage Examples
|
|
|
|
### Basic Usage
|
|
|
|
```go
|
|
import (
|
|
"github.com/tutus-one/tutus-chain/pkg/storage"
|
|
"github.com/tutus-one/tutus-chain/pkg/storage/local"
|
|
)
|
|
|
|
// Create provider
|
|
provider, err := local.New(local.Config{
|
|
Path: "/var/lib/tutus/storage",
|
|
})
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
defer provider.Close()
|
|
|
|
// Store data
|
|
id, err := provider.Put(ctx, strings.NewReader("block data"), storage.PutOptions{
|
|
ContentType: "application/octet-stream",
|
|
Attributes: map[string]string{
|
|
"block_index": "12345",
|
|
},
|
|
})
|
|
|
|
// Retrieve data
|
|
reader, err := provider.Get(ctx, id)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
defer reader.Close()
|
|
data, _ := io.ReadAll(reader)
|
|
```
|
|
|
|
### Registry Pattern
|
|
|
|
```go
|
|
// Create registry with multiple providers
|
|
registry := storage.NewRegistry()
|
|
registry.Register(neofsAdapter)
|
|
registry.Register(localAdapter)
|
|
|
|
// Get provider by name
|
|
provider, ok := registry.Get("neofs")
|
|
if !ok {
|
|
// Fallback to local
|
|
provider, _ = registry.Get("local")
|
|
}
|
|
```
|
|
|
|
## Implementing Custom Providers
|
|
|
|
To add support for a new storage backend:
|
|
|
|
1. Create a new package under `pkg/storage/`
|
|
2. Implement the `storage.Provider` interface
|
|
3. Optionally implement `BlockStorage` or `StateStorage`
|
|
4. Add configuration to `storage.Config`
|
|
|
|
Example structure:
|
|
|
|
```
|
|
pkg/storage/
|
|
├── storage.go # Core interfaces
|
|
├── config.go # Configuration types
|
|
├── errors.go # Error definitions
|
|
├── neofs/ # NeoFS adapter
|
|
│ └── adapter.go
|
|
├── local/ # Local filesystem adapter
|
|
│ └── adapter.go
|
|
└── mycloud/ # Custom provider
|
|
└── adapter.go
|
|
```
|
|
|
|
## Security Considerations
|
|
|
|
1. **Encryption at Rest**: Enable storage-level encryption for sensitive data
|
|
2. **Access Control**: Use provider-specific ACLs to restrict access
|
|
3. **Audit Logging**: Enable logging for all storage operations
|
|
4. **Key Management**: Use HSMs or secure key storage for encryption keys
|
|
5. **Network Security**: Encrypt all traffic between nodes and storage
|
|
|
|
## Performance Tuning
|
|
|
|
### NeoFS
|
|
- Increase `timeout` for large objects
|
|
- Use multiple endpoints for load balancing
|
|
- Configure appropriate `session_expiration_duration`
|
|
|
|
### Local Storage
|
|
- Use SSDs for best performance
|
|
- Enable compression for storage efficiency
|
|
- Set appropriate `max_size` to prevent disk exhaustion
|
|
|
|
### S3
|
|
- Enable transfer acceleration where available
|
|
- Use regional endpoints for lower latency
|
|
- Configure appropriate retry policies
|
|
|
|
## Monitoring
|
|
|
|
Key metrics to monitor:
|
|
|
|
| Metric | Description |
|
|
|--------|-------------|
|
|
| `storage_put_duration_seconds` | Time to store objects |
|
|
| `storage_get_duration_seconds` | Time to retrieve objects |
|
|
| `storage_errors_total` | Total storage errors by type |
|
|
| `storage_objects_total` | Total objects stored |
|
|
| `storage_bytes_total` | Total bytes stored |
|
|
|
|
## Troubleshooting
|
|
|
|
### Common Issues
|
|
|
|
**ErrNotFound**
|
|
- Object was deleted or never stored
|
|
- Check object ID format
|
|
|
|
**ErrConnectionFailed**
|
|
- Storage backend is unreachable
|
|
- Check network connectivity and firewall rules
|
|
|
|
**ErrQuotaExceeded**
|
|
- Storage limits reached
|
|
- Increase quota or clean up old data
|
|
|
|
**ErrTimeout**
|
|
- Operation took too long
|
|
- Increase timeout or check network latency
|