Sealing-as-a-Service API Design #9079
Replies: 15 comments 23 replies
-
Hey @dleonx ! Thanks for starting this discussion. We've taken a first pass at demonstrating a potential communication flow between Sealing/SNARK providers and Lotus based on the architecture presented. We've tried to capture what we think are the important general JSON key/values, but the exact fields and data structures should ultimately be defined based on Lotus objects. Please feel free to ask if you have any questions and feedback is greatly appreciated. BatchAssignSectorIDs (Assign SectorID in Diagram) Sealing-as-a-Service > Lotus This API asks Lotus to reserve a number of sectors (1-n) and returns the metadata required to create the replica_ID.
BatchNotifyPrecommitComplete (SendSector in Diagram) Sealing-as-a-Service > Lotus This API call lets Lotus know that PC1 and PC2 are complete. The information required for Lotus to do the Precommit is in the "SealedCID" field. If TrustSector was set to 1 then Lotus can proceed to post the Precommit message without downloading and verifying the rest of the sector data. The replica and trees can be found in the "OutPath".
BatchDoCommits (RemoteCommit1/Commit2 in Diagram) Lotus > Sealing-as-a-Service This API for the Sealing-as-a-Service provider tells them to begin performing C1 and optionally C2 and provides them with the required WaitSeed information.
BatchDoSNARK (Commit2 in Diagram) Lotus > SNARK-as-a-Service This API asks a Snark-as-a-Service provider to compute a SNARK.
BatchNotifyCommitComplete Sealing/SNARK-as-a-Service > Lotus This API lets Lotus know that C1 and/or C2 has been completed and is ready to be used.
BatchFinalizePoRepSectors (Proving in Diagram) Lotus > Sealing-as-a-Service This API to the Sealing-as-a-Service provider lets them know that the Commit message has been successfully posted on chain and the sector data can be deleted from the service.
|
Beta Was this translation helpful? Give feedback.
-
To expand on this a little, here's an example template of worker interfaces which can be easily adapted to pass work to SaaS - https://gist.github.com/magik6k/0fc17efc07f5ffc7960911d3c3e5fd05. After you get a worker serving its rpc, you just need to call WorkerConnect on lotus-miner API to have lotus-miner start passing C2 tasks to it - here's how lotus-worker does that - https://github.com/filecoin-project/lotus/blob/master/cmd/lotus-worker/main.go#L660
You can use miner state diffing or state inspection helpers to monitor when sectors get proven on-chain. |
Beta Was this translation helpful? Give feedback.
-
@dleonx could you please ask the related parties to review Magik's feedback soon, i.e: confirm whether registering workers are something thats feasible/reasonable for them to do? If not, please let us know and we will propose design accordingly! |
Beta Was this translation helpful? Give feedback.
-
First, we must admit that our design is not perfect. And here is our design diagram. Control-key is the trick. Pandarua is one of our products. It can help users to buy sectors, track the sealing process, etc. Pros:
cons
|
Beta Was this translation helpful? Give feedback.
-
Thanks for the feedback @magik6k! Below are our thoughts/feedback on the various APIs. One additional piece of context I’d like to provide is that as we drafted the API the goal was to eliminate the requirement to run a ‘sidecar’ alongside the Lotus node. We hope with the proper API we can have direct interaction between Lotus and Sealing/SNARK providers without any duplication of logic from Lotus such as chain interaction or storage management. In an ideal world (from our perspective) the service is purely computational and is designed to offload the heaviest computations and reduce the hardware requirements and cost of sealing for storage providers. BatchAssignSectorIDs BatchNotifyPrecommitComplete BatchNotifySealingOperationComplete
BatchDoCommits BatchNotifyCommitComplete BatchFinalizePoRepSectors |
Beta Was this translation helpful? Give feedback.
-
We already have a lot of other APIs dealing with data in this format, and I'd think that it's really easy to deal with it in pretty much any language. In Go you can use our bitfield library; I'd imagine other languages have libraries for it too, but fundamentally it should be really easy to just encode/decode the json rle array with 1/2 lines of map/reduce into any other form you need. https://github.com/filecoin-project/lotus/pull/9183/files#diff-11f17642f37c68a4e8373aa8612f2ab0c0160e516b7d071e8d9f3922764f010eR127-R131 Implements a call which makes it possible to reserve ranges of sector numbers (
in many lotus clusters today the main lotus-miner process will have no local access to storage, and it will only be accessible from workers, and in some cases not all workers will have access to all the storage. This is done because at certain scales you simply can't push all the bytes through a single computer, even if it has multiple 100G NICs. Given that SaaS is meant to work/exceed those scales, we should start with something that will work at those scales. One solution that could work is:
(tldr after sector is sealed, saas would give sector metadata+sector urls to lotus; lotus(-workers) would later fetch those files)
There are some other sector states in which it makes sense to import sectors:
That's not really the case; If your worker declares itself as having no resource constraints, lotus will just forward all C2 calls to your service with no scheduling logic getting in the way. It's also worth noting that all lotus<->worker calls are async http (jsonrpc) calls, so there's no need to worry about keeping connections alive; Abstractly this is roughly the http requests which happen between lotus / c2 workers:
Agree that this is useful
Not sure if we really want or need all methods to support batching - it really depends what you want to achieve with it.
|
Beta Was this translation helpful? Give feedback.
-
Hello, team, Venus team believe that SaaS initiative is highly compatible with the design philosophy of |
Beta Was this translation helpful? Give feedback.
-
Hey @magik6k thanks for all of the feedback! I think we are mostly in agreement on the API approach. Below is a quick summary of where I think we're at. BatchAssignSectorIDs BatchNotifyPrecommitComplete / BatchNotifySealingOperationComplete / RecieveSector BatchDoCommits BatchFinalizePoRepSectors As for batching, our assumption was that the standard working model would be that many sectors would be requested to be sealed at once, and our sealing software seals many sectors in parallel as well. However, if it adds complexity to have batch APIs then it is no problem to make repeated API calls. Have a great weekend! |
Beta Was this translation helpful? Give feedback.
-
Hi, Out of the graphics, I find it a bit hard to understand the actual data movement steps for incoming deal data. @dleonx ? Is this because it is assumed that a SaaS solution with have their own boost/market implementation that will do the Graphsync/HTTP transfers directly to their datacenter, so no deal data is never received or processed on the lotus-miner (SP) side? |
Beta Was this translation helpful? Give feedback.
-
@Fatman13 @hexcola thank you for providing designs! We want to make sure that all services will be compatible with the generic interface that gets implemented. Do you have any specific feedback related to the architecture and conversations that have followed in this thread? We'd love to get your input. |
Beta Was this translation helpful? Give feedback.
-
@magik6k shall provide more technical details later, tho after prototyping and careful consideration, we can see a value supporting remote C2 in lotus, and that will be included in the initial rollout. |
Beta Was this translation helpful? Give feedback.
-
we would like to try the remote c2 support in lotus |
Beta Was this translation helpful? Give feedback.
-
Nebula Block is interested to participate in testing |
Beta Was this translation helpful? Give feedback.
-
@flyworker @claydrone great! Please sign up through this form: bit.ly/sealingsurvey |
Beta Was this translation helpful? Give feedback.
-
Update on current implementation statusRight now there are 3 PRs in lotus related to this work
Sector number management APIsSectorNumFreeSectorNumFree drops a sector reservation Perms: admin Inputs: [
"reservation-name"
] Response: SectorNumReservationsSectorNumReservations returns a list of sector number reservations Perms: read Inputs: Response: {
"reservation-name": [5, 3],
"other-reservation-name": [12, 5]
} SectorNumReserveSectorNumReserve creates a new sector number reservation. Will fail if any other reservation has colliding Perms: admin Inputs: [
"reservation-name", # name
[5, 3], # to reserve (json-rle)
false # force - set this to false in basically all cases
] Response: SectorNumReserveCountSectorNumReserveCount creates a new sector number reservation for Perms: admin Inputs: [
"reservation-name", # name
42 # number of SectorNumbers to reserve
] Response - json-rle [5, 42] On json-rleSector number ranges are handled as bitfields encoded as an array of run-lengths, always starting with zeroes (absent values) E.g.: The set In Go those lists can be unmarshalled with go-bitfield, in other languages it should be easy to transform this run-length list into any other format with a few map/reduce calls. Sector Import#9210 adds "just" one new miner RPC method - Example json input (values are not all valid): [
{
# State specifies the first state the sector will enter after being imported
# Must be one of the following states:
# * Packing
# * GetTicket
# * PreCommitting
# * SubmitCommit
# * Proving/Available
"State": "PreCommitting",
"Sector": {
"Miner": 1000,
"Number": 9
},
"Type": 8, # RegisteredSealProof
# Required in Packing and later
"Pieces": [
{
"Piece": {
"Size": 1032,
"PieceCID": {"/": "baga6ea4seaqao7s73y24kcutaosvacpdjgfe5pw76ooefnyqw4ynr3d2y6x2mpq"}, # CommP
},
"DealInfo": {
"PublishCid": null,
"DealID": 5432,
"DealProposal": {
"PieceCID": {"/": "baga6ea4seaqao7s73y24kcutaosvacpdjgfe5pw76ooefnyqw4ynr3d2y6x2mpq"}, # CommP
"PieceSize": 1032,
"VerifiedDeal": true,
"Client": "f01234",
"Provider": "f01000",
"Label": "",
"StartEpoch": 10101,
"EndEpoch": 1010100,
"StoragePricePerEpoch": "0",
"ProviderCollateral": "0",
"ClientCollateral": "0"
},
"DealSchedule": {
"StartEpoch": 10101,
"EndEpoch": 1010100
},
"KeepUnsealed": true
}
}
],
# Required in PreCommitting and later
"TicketValue": "Bw==", # base64, 32 bytes of ticket randomness
"TicketEpoch": 10000,
"PreCommit1Out": "Bw==", # see (1) below
"CommD": {"/": "baga6ea4seaqao7s73y24kcutaosvacpdjgfe5pw76ooefnyqw4ynr3d2y6x2mpq"},
"CommR": {"/": "bagboea4b5abcbwhjwgl3vo54uefgs6gq5qkjmar3xg5st56ippg7vzy4nwkxubs3"},
# Required in SubmitCommit and later
"PreCommitInfo": {
"SealProof": 8,
"SectorNumber": 9,
"SealedCID": {"/": "bagboea4b5abcbwhjwgl3vo54uefgs6gq5qkjmar3xg5st56ippg7vzy4nwkxubs3"},
"SealRandEpoch": 10101,
"DealIDs": [
5432
],
"Expiration": 10101,
"UnsealedCid": null
},
"PreCommitDeposit": "0",
"PreCommitMessage": null,
"PreCommitTipSet": [{"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"}, {"/":"bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve"}],
"SeedValue": "Bw==", # base64, 32 bytes of ticket randomness
"SeedEpoch": 10101,
"CommitProof": "Ynl0ZSBhcnJheQ==", # see (2) below
# Required in Proving/Available
"CommitMessage": {"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"},
# Optional sector metadata to import
"Log": [
{
"Kind": "string value",
"Timestamp": 42,
"Trace": "string value",
"Message": "string value"
}
],
# Sector data references - lotus will use those for fetching files into local storage
# * When Local is false, lotus will fetch sector data from provided URLs
# * When Local is true, lotus will assume that sector data is available in the lotus storage system already (e.g. through a SaaS sidecar fetching and declaring sector data to the sector index before calling SectorReceive). This is useful for SaaS implementations which want to use more advanced file transport methods.
"DataUnsealed": {
"Local": false,
"URL": "http://example.com/something/something/miner-567/sector-unsealed-123", # http GET, will be executed by lotus-miner or one of lotus-workers when the DownloadSector task type is enabled; Expects octet-stream with the "unsealed" sector file
"Headers": [
{
"Key": "X-my-header",
"Value": "my-header-value"
}
]
},
"DataSealed": {
"Local": false,
"URL": "http://example.com/something/something/miner-567/sector-sealed-123", # http GET, will be executed by lotus-miner or one of lotus-workers when the DownloadSector task type is enabled; Expects octet-stream with the "sealed" sector file; File names and sizes must match constraints defined in https://github.com/filecoin-project/lotus/blob/6b663d33854a8797435a27de9fa278560d9a56ca/storage/sealer/tarutil/systar.go#L17-L72
"Headers": []
},
"DataCache": {
"Local": false,
"URL": "http://example.com/something/something/miner-567/sector-cache-123", # http GET, will be executed by lotus-miner or one of lotus-workers when the DownloadSector task type is enabled; returned data must be a TAR of the "cache" sector directory
"Headers": []
},
# Sealing service hooks (all are optional)
"RemoteCommit1Endpoint": "http://example.com/something/something/miner-567/c1", # http POST, request body is json-ified https://github.com/filecoin-project/lotus/blob/6b663d33854a8797435a27de9fa278560d9a56ca/api/api_storage.go#L584-L591, return value is json of https://github.com/filecoin-project/rust-filecoin-proofs-api/blob/11126c5b91dca942712cf632917a0027634dfddf/src/seal.rs#L154-L162 (same as in (2) below)
"RemoteCommit2Endpoint": "http://example.com/something/something/miner-567/c2", # http POST, request body is json https://github.com/filecoin-project/lotus/blob/6b663d33854a8797435a27de9fa278560d9a56ca/api/api_storage.go#L593-L599, Commit1Out is described in (2) below
"RemoteSealingDoneEndpoint": "http://example.com/something/something/miner-567/done" # http POST, request body is https://github.com/filecoin-project/lotus/blob/6b663d33854a8797435a27de9fa278560d9a56ca/api/api_storage.go#L601-L611
}
]
There is also a simplified integration test which does SaaS style sealing, then imports the sector into lotus-miner with all the http hooks which might be helpful to look at when integrating with this API: lotus/itests/sector_import_simple_test.go Lines 47 to 345 in 6b663d3 |
Beta Was this translation helpful? Give feedback.
-
This is a discussion to define and align on the API for the sealing-as-a-service interface. The interface should reference the example architecture of this issue.
Sealing-as-a-service aims to accelerate the ability to onboard data to the network and facilitate the onboarding of new SPs. New SPs can use a sealing service to onboard to the network without purchasing sealing hardware. Existing SPs can either use sealing-as-a-service to accelerate sealing sectors, or provide sealing-as-a-service to generate new lines of business.
Below is an example sealing architecture in Lotus. Sealing components of this sealing architecture can be extracted into a sealing service. The goal of this discussion is to align on the best way for Lotus to expose a generic interface to enable this service. If you have any design suggestions or feedback, please leave them in this discussion.
Example architecture:
Beta Was this translation helpful? Give feedback.
All reactions