Market Pallet
Table of Contents
Overview
The purpose of the pallet is to manage storage deals between storage market participants and to track their funds. Market Pallet is tightly coupled with Storage Provider Pallet because it's a source of truth for deals. Storage Provider Pallet cannot exist without deal information from Market Pallet.
Extrinsics*
add_balance
Reserves a given amount of currency for usage in the Storage Market.
The reserved amount will be considered free
until it is used in a deal when moved to locked
and used to pay for the deal.
Name | Description | Type |
---|---|---|
amount | The amount to be reserved | Positive integer |
Example
Using the storagext-cli
to add 1_000_000_0001 Plancks to Alice's account with the following command2:
storagext-cli --sr25519-key "//Alice" market add-balance 1000000000
This value is the minimum amount due to Polkadot's existential deposit.
More information available in: <https://support.polkadot.network/support/solutions/articles/65000168651-what-is-the-existential-deposit->.
Read more about the add-balance
command in Storagext CLI/Subcommand market
/add-balance
.
withdraw_balance
Withdraws funds from the Storage Market.
The funds will be withdrawn from the free
balance, meaning that the amount
must be
less than or equal to free
and greater than 0 (\({free} \ge {amount} \gt 0\)).
Name | Description | Type |
---|---|---|
amount | The amount to be withdrawn | Positive integer |
Example
Using the storagext-cli
to withdraw 10000 Plancks from Alice's free
balance using the following command3:
storagext-cli --sr25519-key "//Alice" market withdraw-balance 10000
Read more about the withdraw-balance
command in Storagext CLI/Subcommand market
/withdraw-balance
.
publish_storage_deals
Publishes list of deals to the chain.
This extrinsic must be called by a storage provider.
Name | Description | Type |
---|---|---|
proposal | Specific deal proposal, a JSON object | JSON object, specified in the deal proposal components section |
client_signature | Client signature of this specific deal proposal | MultiSignature , meaning a 64-byte array for Sr25519 and Ed25519 signatures and 65-byte array for ECDSA signatures |
The client_signature
, as the name indicates, is generated by the client by signing the deal proposal with their private key —
the storagext-cli
does this for the user automatically4.
This signature ensures that the storage provider cannot forge a deal with an arbitrary client.
The type of signature is dependent on the key the signer has, currently supported key types are Sr25519, ECDSA and Ed25519.
This step corresponds to the "sign & send proposal" step in the deal overview.
Deal Proposal Components
Name | Description | Type |
---|---|---|
piece_cid | Byte encoded CID | CID |
piece_size | Size of the piece | Positive integer |
client | SS58 address of the storage client | SS58 address |
provider | SS58 address of the storage provider | SS58 address |
label | Arbitrary client chosen label | String, with a maximum length of 128 characters |
start_block | Block number on which the deal should start | Positive integer |
end_block | Block number on which the deal should end | Positive integer, end_block > start_block |
storage_price_per_block | Price for the storage specified per block5 | Positive integer, in Plancks |
provider_collateral | Collateral which is slashed if the deal fails | Positive integer, in Plancks |
state | Deal state. Can only be set to Published | String |
See the original Filecoin specification for details.
Example
Using the storagext-cli
to publish deals with //Alice
as the storage provider and //Charlie
as the client by running the following command6:
storagext-cli --sr25519-key "//Alice" market publish-storage-deals \
--client-sr25519-key "//Charlie" \
"@deals.json"
Where deals.json
is a file with contents similar to:
[
{
"piece_cid": "bafk2bzacecg3xxc4f2ql2hreiuy767u6r72ekdz54k7luieknboaakhft5rgk",
"piece_size": 1337,
"client": "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y",
"provider": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
"label": "Super Cool (but secret) Plans for a new Polkadot Storage Solution",
"start_block": 69,
"end_block": 420,
"storage_price_per_block": 15,
"provider_collateral": 2000,
"state": "Published"
},
{
"piece_cid": "bafybeih5zgcgqor3dv6kfdtv3lshv3yfkfewtx73lhedgihlmvpcmywmua",
"piece_size": 1143,
"client": "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y",
"provider": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
"label": "List of problematic (but flying) Boeing planes",
"start_block": 1010,
"end_block": 1997,
"storage_price_per_block": 1,
"provider_collateral": 3900,
"state": "Published"
}
]
client_signature
parameter but a keypair that can sign it.
We are aware that this is not secure. However, the system is still under development and is not final; it is a testing tool.
Take into account that the CLI is currently for demo purposes, the authors are aware that the command isn't safe since it requires the private keys of both parties.
The formula to calculate the total price is as follows: \[total\_price = (end\_block - start\_block) * storage\_price\_per\_block\].
Read more about the publish-storage-deals
command in Storagext CLI/Subcommand market
/publish-storage-deals
.
settle_deal_payments
Settle specified deals between providers and clients.
Both clients and providers can call this extrinsic. However, since the settlement is the mechanism through which the provider gets paid, a client has no reason to call this extrinsic. Non-existing deal IDs will be ignored.
Name | Description | Type |
---|---|---|
deal_ids | List of the deal IDs to be settled | Array of integers |
Example
Using the storagext-cli
to settle deal payments for IDs 97, 1010, 1337 and 42069 using the following command7:
storagext-cli --sr25519-key "//Alice" market settle-deal-payments 97 1010 1337 42069
Read more about the settle-deal-payments
command in Storagext CLI/Subcommand market
/settle-deal-payments
Events
The Market Pallet emits the following events:
BalanceAdded
- Indicates that some balance was added as free to the Market Pallet account for usage in the storage market.who
- SS58 address of then account which added balanceamount
- Amount added
BalanceWithdrawn
- Some balance was transferred (free) from the Market Account to the Participant's account.who
- SS58 address of the account which had withdrawn the balanceamount
- Amount withdrawn
DealPublished
- Indicates that a deal was successfully published withpublish_storage_deals
.deal_id
- Unique deal IDclient
- SS58 address of the storage clientprovider
- SS58 address of the storage provider
DealActivated
- Deal's state has changed toActive
.deal_id
- Unique deal IDclient
- SS58 address of the storage clientprovider
- SS58 address of the storage provider
DealsSettled
- Published after thesettle_deal_payments
extrinsic is called. Indicates which deals were successfully and unsuccessfully settled.successful
- List of deal IDs that were settledunsuccessful
- List of deal IDs with the corresponding errors
DealSlashed
- Is emitted when some deal expired.deal_id
- Deal ID that was slashed
DealTerminated
- A deal was voluntarily or involuntarily terminated.deal_id
- Terminated deal IDclient
- SS58 address of the storage clientprovider
- SS58 address of the storage provider
Errors
The Market Pallet actions can fail with following errors:
InsufficientFreeFunds
- Market participants do not have enough free funds.NoProposalsToBePublished
-publish_storage_deals
was called with an empty list ofdeals
.ProposalsPublishedByIncorrectStorageProvider
- Is returned when callingpublish_storage_deals
and the deals in a list are not published by the same storage provider.AllProposalsInvalid
-publish_storage_deals
call was supplied with a list ofdeals
which are all invalid.DuplicateDeal
- There is more than one deal with this ID in the Sector.DealNotFound
- Tried to activate a deal that is not in the system.DealActivationError
- Tried to activate a deal, but data was malformed.- Invalid specified provider.
- The deal already expired.
- Sector containing the deal expires before the deal.
- Invalid deal state.
- Deal is not pending.
DealsTooLargeToFitIntoSector
- Sum of all deals piece sizes for a sector exceeds sector size. The sector size is based on the registered proof type. We currently only support registeredStackedDRG2KiBV1P1
proofs, which have 2KiB sector sizes.TooManyDealsPerBlock
- Tried to activate too many deals at a givenstart_block
.UnexpectedValidationError
-publish_storage_deals
's core logic was invoked with a broken invariant that should be called byvalidate_deals
. Please report an issue to the developers.DealPreconditionFailed
- Due to a programmer bug. Please report an issue to the developers.
Constants
Name | Description | Value |
---|---|---|
MaxDeals | How many deals can be published in a single batch of publish_storage_deals . | 128 |
MaxDealsPerBlock | Maximum deals that can be scheduled to start at the same block. | 128 |
MinDealDuration | Minimum time an activated deal should last. | 5 Minutes (50 Blocks) |
MaxDealDuration | Maximum time an activated deal should last. | 180 Minutes (1800 Blocks) |