full-deals-on-chain

sequenceDiagram

participant RetrievalClient
participant RetrievalProvider

participant StorageMarketParticipant1
participant StorageMarketParticipant2
participant StorageMarketActor

participant PaymentChannelActor
participant PaymentSubsystem

participant BlockchainSubsystem
participant BlockSyncer
participant BlockProducer

participant StoragePowerConsensusSubsystem
participant StoragePowerActor

participant StorageMiningSubsystem
participant StorageMinerActor
participant SectorIndexerSubsystem
participant StorageProvingSubsystem

participant FilecoinProofsSubsystem
participant ClockSubsystem
participant libp2p

Note over RetrievalClient,RetrievalProvider: RetrievalMarketSubsystem
Note over StorageMarketParticipant,StorageMarketActor: StorageMarketSubsystem
Note over BlockchainSubsystem,StoragePowerActor: BlockchainGroup
Note over StorageMiningSubsystem,StorageProvingSubsystem: MiningGroup

opt RetrievalMarket
    RetrievalClient ->>+ RetrievalProvider: NewRetrievalQuery(RetreivalQuery)
    RetrievalProvider -->>- RetrievalClient: RetrievalQueryResponse
    RetrievalClient ->>+ RetrievalProvider: NewRetrievalDealProposal(RetrievalDealProposal)
    RetrievalProvider -->> RetrievalProvider: AcceptRetrievalDealProposal(RetrievalDealPropsal)
    RetrievalProvider -->>- RetrievalClient: NewPaymentChannel
end

opt RegisterStorageMiner
    StorageMiningSubsystem ->> StorageMiningSubsystem: CreateMiner(ownerPubKey PubKey, workerPubKey PubKey, pledgeAmt TokenAmount)
    StorageMiningSubsystem ->>+ StoragePowerActor: CreateStorageMiner(OwnerAddr, WorkerPubKey)
    StoragePowerActor -->>- StorageMiningSubsystem: StorageMinerActor
end

opt StorageDealMake
    StorageMarketParticipant1 -->> StorageMarketActor: RegisterParticipant(TokenAmount)
    StorageMarketParticipant1 -->> StorageMarketActor: AddBalance(TokenAmount)
    StorageMarketParticipant1 -->> StorageMarketActor: WithdrawBalance(TokenAmount)
    StorageMarketParticipant1 -->+ StorageMarketActor: CheckLockedBalance(Address)
    StorageMarketActor -->- StorageMarketParticipant1: TokenAmount


    StorageMarketParticipant1 -->+ StorageMarketParticipant2: NewStorageDealProposal(StorageDealProposal)
    StorageMarketParticipant2 --> StorageMarketActor: VerifyBalance(StorageMarketParticipant1)
    StorageMarketParticipant2 -->> StorageMarketParticipant2: SignStorageDealProposal(StorageDealProposal)
    StorageMarketParticipant2 -->- StorageMarketParticipant1: NewStorageDeal(StorageDeal)
    StorageMarketParticipant2 -->> StorageMarketActor: PublishStorageDeal(StorageDeal)
    StorageMarketParticipant1 -->> StorageMarketActor: PublishStorageDeal(StorageDeal)

end

opt AddingDealToSector
    StorageMarketActor ->>+ StorageMiningSubsystem: HandleStorageDeal(Deal)
    StorageMiningSubsystem ->>+ SectorIndexerSubsystem: AddDealToSector(Deal, SectorID)
    SectorIndexerSubsystem ->> SectorIndexerSubsystem: IndexSectorByDealExpiration(SectorID, Deal)
    SectorIndexerSubsystem -->>- StorageMiningSubsystem: (SectorID, Deal)
    StorageMiningSubsystem ->>- StorageMarketActor: NotifyStorageDealStaged(Deal,SectorID)
end

opt ClientQuery
    StorageMarketParticipant1 ->>+ StorageMarketParticipant2: QueryStorageDealProposalStatus(StorageDealProposalQuery)
    StorageMarketParticipant2 -->>- StorageMarketParticipant1: StorageDealProposalQueryResponse
    StorageMarketParticipant1 ->>+ StorageMarketParticipant2: QueryStorageDealStatus(StorageDealQuery)
    StorageMarketParticipant2 -->>- StorageMarketParticipant1: StorageDealQueryResponse
end

opt SealingSector
    StorageMiningSubsystem ->>+ StoragePowerConsensusSubsystem: GetSealSeed(Chain, Epoch)
    StoragePowerConsensusSubsystem -->>- StorageMiningSubsystem: Seed
    StorageMiningSubsystem ->>+ StorageProvingSubsystem: SealSector(Seed, SectorID, ReplicaCfg)
    StorageProvingSubsystem ->>+ SectorSealer: Seal(Seed, SectorID, ReplicaCfg)
    SectorSealer -->>- StorageProvingSubsystem: SealOutputs
    StorageProvingSubsystem ->>- StorageMiningSubsystem: SealOutputs
    opt CommitSector
        StorageMiningSubsystem ->> StorageMinerActor: CommitSector(Seed, SectorID, SealCommitment, SealProof, [&Deal], [Deal])
        StorageMinerActor ->>+ FilecoinProofsSubsystem: VerifySeal(SectorID, OnSectorInfo)
        FilecoinProofsSubsystem -->>- StorageMinerActor: {1,0}
        alt 1 - success
            StorageMinerActor ->> StorageMarketActor: AddDeal(SectorID, [&Deal], DealStatusOnChain)
            StorageMinerActor ->> StorageMarketActor: AddDeal(SectorID, [Deal], DealStatusPending)
            StorageMinerActor ->> StoragePowerActor: IncrementPower(StorageMiner.WorkerPubKey)
        else 0 - failure
            StorageMinerActor -->> StorageMiningSubsystem: CommitSectorError
        end
    end
end

loop BlockReception
    BlockSyncer ->>+ libp2p: Subscribe(OnNewBlock)
    libp2p -->>- BlockSyncer: Event(OnNewBlock, block)
    BlockSyncer ->> BlockSyncer: ValidateBlockSyntax(block)
    BlockSyncer ->>+ BlockchainSubsystem: HandleBlock(block)
    BlockchainSubsystem ->> BlockchainSubsystem: ValidateBlock(block)
    BlockchainSubsystem ->> StoragePowerConsensusSubsystem: ValidateBlock(block)
    BlockchainSubsystem ->> FilecoinProofsSubsystem: ValidateBlock(block)
    BlockchainSubsystem ->>- BlockchainSubsystem: StateTree ← TryGenerateStateTree(block)

    opt Round Cutoff
        WallClock -->> BlockchainSubsystem: AssembleTipsets()
        BlockchainSubsystem ->> BlockchainSubsystem: [Tipset] ← AssembleTipsets()
        BlockchainSubsystem ->> BlockchainSubsystem: Tipset ← ChooseTipset([Tipset])
        BlockchainSubsystem ->> Blockchain: ApplyStateTree(StateTree)
    end
end

loop BlockProduction
    alt New Tipset
        BlockchainSubsystem ->> StorageMiningSubsystem: OnNewTipset(Chain, Epoch)
    else Null block last round
        WallClock ->> StorageMiningSubsystem: OnNewRound()
        Note Right of WallClock: epoch is incremented by 1
    end
    StorageMiningSubsystem ->>+ StoragePowerConsensusSubsystem: GetElectionArtifacts(Chain, Epoch)
    StoragePowerConsensusSubsystem ->> StoragePowerConsensusSubsystem: TK ← TicketAtEpoch(Chain, Epoch-k)
    StoragePowerConsensusSubsystem ->> StoragePowerConsensusSubsystem: T1 ← TicketAtEpoch(Chain, Epoch-1)
    StoragePowerConsensusSubsystem -->>- StorageMiningSubsystem: TK, T1

    loop forEach StorageMiningSubsystem.StorageMiner
        StorageMiningSubsystem ->> StorageMiningSubsystem: EP ← DrawElectionProof(TK.randomness(), StorageMiner.WorkerKey)
        alt New Tipset
            StorageMiningSubsystem ->> StorageMiningSubsystem: T0 ← GenerateNextTicket(T1.randomness(), StorageMiner.WorkerKey)
        else Null block last round
            StorageMiningSubsystem ->> StorageMiningSubsystem: T1 ← GenerateNextTicket(T0.randomness(), StorageMiner.WorkerKey)
            Note Right of StorageMiningSubsystem: Using tickets derived in failed election proof in last epoch
        end
        StorageMiningSubsystem ->>+ StoragePowerConsensusSubsystem: TryLeaderElection(EP)
        StoragePowerConsensusSubsystem -->>- StorageMiningSubsystem: {1, 0}
        opt 1- success
            StorageMiningSubsystem ->>+ StoragePowerConsensusSubsystem: GetPoStChallenge(Chain, Epoch)
            StoragePowerConsensusSubsystem -->>- StorageMiningSubsystem: challenge
            StorageMiningSubsystem ->>+ StorageProvingSubsystem: GeneratePoSt(challenge, [SectorID])
            StorageProvingSubsystem -->>- StorageMiningSubsystem: PoStProof
            opt SubmitPoSt
                StorageMiningSubsystem ->> StorageMinerActor: SubmitPoSt(PoStProof, DoneSet)
                StorageMinerActor ->>+ FilecoinProofsSubsystem: VerifyPoSt(PoStProof)
                FilecoinProofsSubsystem -->>- StorageMinerActor: {1,0}
                alt 1 - success
                    StorageMinerActor ->> StorageMinerActor:  UpdateDoneSet()
                    StorageMinerActor ->> StorageMarketActor: HandleStorageDealPayment()
                    StorageMarketActor ->> StorageMarketActor: CloseExpiredStorageDeal()
                else 0 - failure
                    StorageMinerActor -->> StorageMiningSubsystem: PoStError
                    StorageMarketActor -->> StorageMarketActor: SlashStorageCollateral()
                end
            end

            StorageMiningSubsystem ->> BlockProducer: GenerateBlock(EP, T0, Tipset, StorageMiner.Address)
            BlockProducer ->>+ MessagePool: GetMostProfitableMessages(StorageMiner.Address)
            MessagePool -->>- BlockProducer: [Message]
            BlockProducer ->> BlockProducer: block ← AssembleBlock([Message], Tipset, EP, T0, StorageMiner.Address)

            BlockProducer ->> BlockSyncer: PropagateBlock(block)
        end
    end
end

opt MiningScheduler
    opt Expired deals
        BlockchainSubsystem ->> SectorIndexerSubsystem: OnNewTipset(Chain, Epoch)
        SectorIndexerSubsystem ->> SectorIndexerSubsystem: [SectorID] ← LookupSectorByDealExpiry(Epoch)
        SectorIndexerSubsystem ->> SectorIndexerSubsystem: PurgeSectorsWithNoLiveDeals([SectorID])
        SectorIndexerSubsystem ->>+ StorageMiningSubsystem: HandleExpiredDeals([SectorID])
        StorageMiningSubsystem ->>- StorageMarketActor: CloseExpiredStorageDeal(StorageDeal)
    end
    Note Right of MiningScheduler: Schedule and resume PoSts
    Note Right of MiningScheduler: Schedule and resume SEALs
    Note Right of MiningScheduler: Maintain FaultSet
    Note Right of MiningScheduler: Maintain DoneSet
end

opt ClockSubsystem
    Note Right of ClockSubsystem: PoSt challenge if a node has not mined a block in a ProvingPeriod
    ClockSubsystem ->>+ StoragePowerConsensusSubsystem: GetPoStChallenge(Chain, Epoch)
    StoragePowerConsensusSubsystem -->>- StorageMiningSubsystem: challenge
    StorageMiningSubsystem ->>+ StorageProvingSubsystem: GeneratePoSt(challenge, [SectorID])
    StorageProvingSubsystem -->>- StorageMiningSubsystem: PoStProof
    opt SubmitPoSt
        StorageMiningSubsystem ->> StorageMinerActor: SubmitPoSt(PoStProof, DoneSet)
        StorageMinerActor ->>+ FilecoinProofsSubsystem: VerifyPoSt(PoStProof)
        FilecoinProofsSubsystem -->>- StorageMinerActor: {1,0}
        alt 1 - success
            StorageMinerActor ->> StorageMinerActor:  UpdateDoneSet()
            StorageMinerActor ->> StorageMarketActor: HandleStorageDealPayment()
            StorageMarketActor ->> StorageMarketActor: CloseExpiredStorageDeal()
        else 0 - failure
            StorageMinerActor -->> StorageMiningSubsystem: PoStError
            StorageMarketActor -->> StorageMarketActor: SlashStorageCollateral()
        end
    end
end

opt Storage Fault
    opt Declaration before receiving a challenge
        StorageMinerSubsystem ->> StorageMinerActor: UpdateSectorStatus([FaultSet], SectorStateSets)
        StorageMinerActor ->> StoragePowerActor: RecomputeMinerPower()
        StorageMarketActor -->> StorageMarketActor: SlashStorageCollateral()
        Note Right of StorageMinerActor: SectorStateSets := (FaultSet, RecoverSet, ExpireSet)
    end

    loop EveryBlock
        loop forEach StorageMinerActor in StoragePowerActor.Miners
            opt if miner ProvingPeriod ends
                StoragePowerActor ->> StorageMinerActor: ProvingPeriodUpdate()
                StorageMinerActor ->> StorageMinerActor: computeProvingPeriodEndSectorState()
                Note Right of StorageMinerActor: FaultSet is all sectors if no post submitted
                Note Right of StorageMinerActor: sectors Faulted longer than threshold proving periods are destroyed
                StorageMinerActor ->> StorageMinerActor: UpdateSectorStatus(newSectorState)
                StorageMinerActor ->> StoragePowerActor: RecomputeMinerPower()
                StorageMinerActor ->> StorageMarketActor: HandleFailedDeals([newSectorState.DestroyedSet])
            end
        end
    end
end

opt Consensus Fault
    StorageMinerActor -->> StoragePowerActor: DeclareConsensusFault(ConsensusFaultProof)
    StoragePowerActor -->+ StoragePowerConsensusSubsystem: ValidateFault(ConsensusFaultProof)

    opt Valid Fault
        StoragePowerConsensusSubsystem -->> StoragePowerActor: TerminateMiner(Address)
        StoragePowerConsensusSubsystem -->> StoragePowerActor: SlashPledgeCollateral(Address)
        StoragePowerConsensusSubsystem -->- StorageMinerActor: UpdateBalance(Reward)
    end
end

Last updated