This is an iteration on part of FIL+ indefinite term limits, exploring the design of FIL+ data cap as a fungible token.
The verified registry actor will perform multiple significant tasks:
- Account for the verifiers (notaries) and verified clients data cap allowances
- Track the allocations of data cap to specified pieces
- Track the claims of data cap by sectors
These need to be broken into three separate actors.
Verified Registry actor
This actor controls minting of the data cap token and tracks allocations of data cap to specific pieces (we could maybe even break out these claims to a new actor).
Verifiers have ability to mint tokens to clients. The verifiers’ minting allowance isn’t represented as a token.
When data cap is allocated, the registry transfers data cap balance to its own account. Its balance represents allocated but not yet claimed data cap.
When an allocation is claimed, the registry burns the associated data cap tokens.
type StoragePower = BigInt // bytes
type Allocation struct {
Client Address // Could drop this if it's in the map key
Provider Address // Optional
Piece CID
Size uint64
TermMinimum uint64
TermMaximum uint64
Expiration Epoch
AllOrNothing bool // Optional? Require atomic commit of entire piece
}
State {
root_key: Address,
// HAMT[Address]StoragePower
// Maps verifiers to their minting allowance.
verifiers: Cid,
remove_data_cap_proposal_ids: Cid,
// Allocations by client, then by ID.
allocations: HAMT[Address]AMT[AllocID]Allocation
next_allocation_id: uint64
// TODO: verifier delegates (like markets)
}
// Add minting allowance to a verifier.
// Callable only by root key.
fn add_verifier({address: Address, allowance: StoragePower})
fn remove_verifier(address: Address)
// Mints tokens to an address and decreases caller's minting allowance.
// Callable by verifier.
fn add_verified_client({address: Address, allowance: StoragePower})
// Burns tokens.
// Callable by root.
fn remove_verified_data_cap({...})
// Called by a verified client, or a delegate, to allocate some of its
// data cap balance to specific pieces and providers.
// Creates an allocation record and transfers the appropriate data cap
// token to this registry's balance.
// Replaces use_bytes.
fn allocate_data_cap({allocations: []DataCapAllocation})
// Cleans up all expired allocations for client.
// Data cap for removed allocations is transferred back to client's balance.
// Note that un-expired allocations cannot be revoked.
// Replaces restore_bytes.
fn revoke_allocations({client: Address})
// Called by storage miner actor to claim allocations for data
// provably committed to storage.
// Burns the associated data cap tokens from this actor's balance.
fn claim_allocations({sectors: ...}) -> {...}
Data cap fungible token actor
This token is in whole units only (representing bytes).
Data cap claim non-fungible token actor
Design notes
- The existing methods use a BigInt representing storage power bytes. Token APIs may expect a TokenAmount (18 dp) value. Internal state can use the byte values, but there’s possibility for confusion.